Why does ComboB need a SelectionChanged event? You can just bind the selected item directly into a property on the VM.
The way i have tackled this previously was to bind ComboA's selected item into the VM. In the setter for that property, i recalculate the available items for ComboB and assign them to another property on the VM, and ComboB's ItemsSource is bound to this property. Of course that property will notify (using INotifyPropertyChanged), but nothing else needed to be done, my ComboB did not have a SelectionChanged event. By using this method i didn't need a SelectionChanged on ComboA either, which keeps the view's code behind nice and sparse - everything is handled in the VM and regular databinding takes care of the rest.
Edit:
Here is an example of adjusting the required lists from within the property setters:
public class MyViewModel : INotifyPropertyChanged
{
public List<SomeObject> ComboAList
{
get { return _comboAList; }
set { _comboAList = value; }
}
public List<SomeObject> ComboBList
{
get { return _comboBList; }
set
{
_comboBList = value;
OnPropertyChanged("ComboBList");
}
}
public List<SomeObject> DataGridList
{
get { return _datagridList; }
set
{
_datagridList = value;
OnPropertyChanged("DataGridList");
}
}
public SomeObject FirstSelectedItem
{
get { return _firstSelectedItem; }
set
{
_firstSelectedItem = value;
RefreshListForComboB();
}
}
public SomeObject SecondSelectedItem
{
get { return _secondSelectedItem; }
set
{
_secondSelectedItem = value;
RefreshListForDataGrid();
}
}
private void RefreshListForComboB()
{
ComboBList = doSomethingThatReturnsAListForComboB();
}
private void RefreshListForDataGrid()
{
DataGridList = doSomethingThatReturnsAListForDataGrid();
}
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private List<SomeObject> _comboAList, _comboBList, _datagridList;
private SomeObject _firstSelectedItem, _secondSelectedItem;
}
And here is a slightly different way to do it, using a PropertyChange event handler on the VM, this simply changes where the list updating happens. This is arguably a better way of doing it than the first sample as it means the property setters don't have 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;
}
}
public List<SomeObject> ComboAList
{
get { return _comboAList; }
set { _comboAList = value; }
}
public List<SomeObject> ComboBList
{
get { return _comboBList; }
set
{
_comboBList = value;
OnPropertyChanged("ComboBList");
}
}
public List<SomeObject> DataGridList
{
get { return _datagridList; }
set
{
_datagridList = value;
OnPropertyChanged("DataGridList");
}
}
public SomeObject FirstSelectedItem
{
get { return _firstSelectedItem; }
set
{
_firstSelectedItem = value;
OnPropertyChanged("FirstSelectedItem");
}
}
public SomeObject SecondSelectedItem
{
get { return _secondSelectedItem; }
set
{
_secondSelectedItem = value;
OnPropertyChanged("SecondSelectedItem");
}
}
private void RefreshListForComboB()
{
ComboBList = doSomethingThatReturnsAListForComboB();
}
private void RefreshListForDataGrid()
{
DataGridList = doSomethingThatReturnsAListForDataGrid();
}
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private List<SomeObject> _comboAList, _comboBList, _datagridList;
private SomeObject _firstSelectedItem, _secondSelectedItem;
}