The correct way is to use the MVVM template and create the ViewModel as follows:
public class MainWindowViewModel : INotifyPropertyChanged { private People _myPeeps; private Person _selectedPerson; public event PropertyChangedEventHandler PropertyChanged; public People MyPeeps { get { return _myPeeps; } set { if (_myPeeps == value) { return; } _myPeeps = value; RaisePropertyChanged("MyPeeps"); } } public Person SelectedPerson { get { return _selectedPerson; } set { if (_selectedPerson == value) { return; } _selectedPerson = value; RaisePropertyChanged("SelectedPerson"); } } private void RaisePropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } }
Initialize it in your view code like this:
public partial class MainWindow : Window { private readonly MainWindowViewModel _viewModel; public MainWindow() { _viewModel = new MainWindowViewModel(); _viewModel.MyPeeps = new People(); _viewModel.MyPeeps.Add(new Person("Fred")); _viewModel.MyPeeps.Add(new Person("Jack")); _viewModel.MyPeeps.Add(new Person("Jill")); DataContext = _viewModel; InitializeComponent(); } }
And bind the data like this:
<Window x:Class="WpfApplication3.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> <Grid.ColumnDefinitions> <ColumnDefinition Width="160" /> <ColumnDefinition Width="3" /> <ColumnDefinition Width="1*" /> </Grid.ColumnDefinitions> <DockPanel Grid.Column="0"> <ListBox SelectedItem="{Binding SelectedPerson}" DisplayMemberPath="Name" ItemsSource="{Binding MyPeeps}" /> </DockPanel> <DockPanel Grid.Column="2"> <StackPanel> <Label>Name</Label> <TextBox Text="{Binding SelectedPerson.Name}" /> </StackPanel> </DockPanel> </Grid> </Window>
Binding will work as follows:
An instance of ViewModel is installed in the DataContext of the window itself. Since the ListBox and TextBox do not indicate any DataContext , they inherit it from the window. Bindings on an object always work relative to a DataContext if nothing is specified. This means that the TextBox binding looks for the SelectedPerson property in its DataContext (i.e. In MainWindowViewModel ) and for the Name property in that SelectedPerson .
The basic mechanics of this sample are as follows: The SelectedPerson property in the ViewModel is always synchronized with the SelectedItem of the ListBox , and the Text TextBox property is always synchronized with the Name SelectedPerson property.
source share