Why does ComboB need a SelectionChanged event? You can simply bind the selected item directly to a property in the virtual machine.
The way I did this earlier was to associate the selected ComboA element with the VM. In the installer for this property, I recount the available elements for ComboB and assign them to another property in the virtual machine, and ComboB ItemsSource is bound to this property. Of course, this property will notify (using INotifyPropertyChanged), but there was nothing else to do, my ComboB did not have a SelectionChanged event. Using this method, I also donβt need SelectionChanged on ComboA, which keeps the view code beautiful and sparse - everything is processed in a virtual machine, and regular data binding takes care of the rest.
Edit:
The following is an example of setting up required lists from property sets:
public class MyViewModel : INotifyPropertyChanged { //ItemsSource of ComboA is bound to this list public List<SomeObject> ComboAList { get { return _comboAList; } set { _comboAList = value; } } //ItemsSource of ComboB is bound to this list public List<SomeObject> ComboBList { get { return _comboBList; } set { _comboBList = value; OnPropertyChanged("ComboBList"); } } //ItemsSource of the dataGrid is bound to this list public List<SomeObject> DataGridList { get { return _datagridList; } set { _datagridList = value; OnPropertyChanged("DataGridList"); } } //SelectedItem of ComboA is bound to this property public SomeObject FirstSelectedItem { get { return _firstSelectedItem; } set { _firstSelectedItem = value; RefreshListForComboB(); } } //SelectedItem of ComboB is bound to this property public SomeObject SecondSelectedItem { get { return _secondSelectedItem; } set { _secondSelectedItem = value; RefreshListForDataGrid(); } } private void RefreshListForComboB() { //do whatever is necessary to filter or create a list for comboB ComboBList = doSomethingThatReturnsAListForComboB(); } private void RefreshListForDataGrid() { //do whatever is necessary to filter or create the list for the DataGrid DataGridList = doSomethingThatReturnsAListForDataGrid(); } protected void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
And here is a slightly different way of doing this using the PropertyChange event handler in the virtual machine, it just changes when the list is updated. This is perhaps the best way to do this than the first sample, as this means that property definitions have no side effects:
public class MyViewModel : INotifyPropertyChanged { public MyViewModel() { this.PropertyChanged += new PropertyChangedEventHandler(MyViewModel_PropertyChanged); } private void MyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e) { switch (e.PropertyName) { case "FirstSelectedItem": RefreshListForComboB(); break; case "SecondSelectedItem": RefreshListForDataGrid(); break; } } //ItemsSource of ComboA is bound to this list public List<SomeObject> ComboAList { get { return _comboAList; } set { _comboAList = value; } } //ItemsSource of ComboB is bound to this list public List<SomeObject> ComboBList { get { return _comboBList; } set { _comboBList = value; OnPropertyChanged("ComboBList"); } } //ItemsSource of the dataGrid is bound to this list public List<SomeObject> DataGridList { get { return _datagridList; } set { _datagridList = value; OnPropertyChanged("DataGridList"); } } //SelectedItem of ComboA is bound to this property public SomeObject FirstSelectedItem { get { return _firstSelectedItem; } set { _firstSelectedItem = value; OnPropertyChanged("FirstSelectedItem"); } } //SelectedItem of ComboB is bound to this property public SomeObject SecondSelectedItem { get { return _secondSelectedItem; } set { _secondSelectedItem = value; OnPropertyChanged("SecondSelectedItem"); } } private void RefreshListForComboB() { //do whatever is necessary to filter or create a list for comboB ComboBList = doSomethingThatReturnsAListForComboB(); } private void RefreshListForDataGrid() { //do whatever is necessary to filter or create the list for the DataGrid DataGridList = doSomethingThatReturnsAListForDataGrid(); } protected void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
source share