I am using WPF and an MVVM pattern. All the comboboxes that are bound to lists work fine, but I have a cascading dropdown that uses a CollectionViewSource
for filtering. The filtering works, as does the setter (which while searching for an answer, I saw another person having trouble with), but I am unable to set the initial value. I have tried a few methods, but none seem to affect the selecteditem.
Viewmodel ctor, and Property setter (_ticket.SelectedSubstatus is set in the model constructor):
public TicketViewModel()
{
_ticket = new TicketModel();
SubstatusList = CollectionViewSource.GetDefaultView(GetStatusList());
SubstatusList.Filter = (x) => { return (int)(x as Substatus).IST_MAIN_STATUS == (int)SelectedStatus.IST_STATUS_ID; };
SubstatusList.MoveCurrentTo(_ticket.SelectedSubstatus);
SelectedSubstatus = _ticket.SelectedSubstatus;
Substatus test = (Substatus)SubstatusList.CurrentItem;
}
public Substatus SelectedSubstatus
{
get { return _ticket.SelectedSubstatus; }
set
{
if (value == _ticket.SelectedSubstatus ||value == null)
return;
_ticket.SelectedSubstatus = value;
_ticket.Issue.IS_SUBSTATUS_ID = value.IST_SUBSTATUS_ID;
base.OnPropertyChanged("SelectedSubstatus");
}
}
and here is the combobox XAML
<ComboBox HorizontalAlignment="Stretch" Margin="15,0,0,0"
Name="comboBox1" VerticalAlignment="Bottom"
Grid.Column="2" Grid.Row="1" FontSize="12"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Path=SubstatusList}"
SelectedItem="{Binding Path=SelectedSubstatus, Mode=TwoWay}"
DisplayMemberPath="IST_NAME"/>
The current item from the CollectionViewSource
is null just after being set by MoveCurrentTo(), and when checked by test. What am I doing wrong?
By default, objects are checked if they are equal by reference, not value.
So if _ticket.SelectedSubstatus
does not directly reference an item in SubstatusList
, then the SelectedSubstatus
will be NULL because you are trying to set the SelectedSubstatus
equal to an item that doesn't exist in the SubstatusList
To get around this, overwrite the .Equals()
method of Substatus
to return true if an object's data is the same. For example,
public override bool Equals(object obj)
{
if (obj == null) return false;
if (obj.GetType() != this.GetType()) return false;
return this.Id == ((SubStatus)obj).Id;
}