euanjt euanjt - 1 month ago 14
C# Question

WPF Databinding controls to properties of Combobox item

I am trying to have a WPF window with a combo box, with which you select an item, and then use text boxes below to edit the properties of the currently selected item, eg Name and Age.

How do I do this with Databinding, ie. to bind the name text box to the Name property of the currently selected item in the combobox?

My XAML is

<Window x:Class="BindingTest001.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
>
<Grid>
<TextBox HorizontalAlignment="Left" Height="23" Margin="10,75,0,0" TextWrapping="Wrap" Text="{Binding Path=CURR.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="497"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="10,103,0,0" TextWrapping="Wrap" Text="{Binding Path=CURR.Age, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>
<ComboBox ItemsSource="{Binding Path=MO}" SelectedValue="{Binding Path=CURR, Mode=TwoWay}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="497" Name="MyComboBox"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="322,181,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
</Window>


Where my code behind is

public partial class MainWindow : Window
{
ObservableCollection<myObj> mo;


public MainWindow()
{
InitializeComponent();

mo = new ObservableCollection<myObj>();
mo.Add(new myObj("Test1", 2));
var ct = new MainWindowDatacontext(this);
this.DataContext = ct;
this.MyComboBox.SelectedIndex = 0;
}

private class MainWindowDatacontext : INotifyPropertyChanged
{
MainWindow parent;
myObj curr;
public MainWindowDatacontext(MainWindow mainWindow)
{
this.parent = mainWindow;
}
public ObservableCollection<myObj> MO
{
get
{
return parent.mo;
}
}
public myObj CURR
{
get
{
return curr;
}
set
{
this.curr = value;
}
}

public event PropertyChangedEventHandler PropertyChanged;

public void executePropertyChanged(string s)
{

if(PropertyChanged!=null)
{
PropertyChanged(this.parent, new PropertyChangedEventArgs(s));
}
}
}

private void Button_Click(object sender, RoutedEventArgs e)
{
mo.Add(new myObj("Test2", 10));
}
}


But the databinding only works for the combo box- the text boxes never bind to anything.

myObj is very simple:

public class myObj : INotifyPropertyChanged
{

public event PropertyChangedEventHandler PropertyChanged;
public void propertyChanged(string s)
{
if(PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(s));
}
}


string name;

public string Name
{
get { return name; }
set {
name = value;
propertyChanged("Name");
}
}
int age;


public myObj(string p1, int p2)
{
this.name = p1;
this.age = p2;
}

public int Age
{
get { return age; }
set { age = value;
propertyChanged("Age");
}
}

public override string ToString()
{
return String.Format("{0}, {1}", name, age);
}
}

Answer

Because you want to bind to the property of another element in your application you should use Binding.ElementName Property. So Change your TextBox's Binding like this:

Text="{Binding SelectedItem.Name, ElementName=MyComboBox,  Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
Text="{Binding SelectedItem.Age, ElementName=MyComboBox, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
Comments