Reputation: 1731
I have ComboBoxes
in my WPF application that get selected by using the SelectedValue
and SelectedValuePath
. Sometimes the SelectedValue
is not part of the ItemsSource
(because the database is inconsistent).
Example:
Items = new ObservableCollection<Item>()
{
new Item() { Id = "1", Text = "Text 1" },
new Item() { Id = "2", Text = "Text 2" },
};
SelectedValue = "3";
When the ComboBox
is loaded and no other value is selected, the SelectedValue
property is still the inconsistent value ("3" in the example). Is there a way to let the binding automatically clear the SelectedValue
when it is not a part of the ItemsSource
?
View:
<ComboBox ItemsSource="{Binding Items}"
SelectedValuePath="Id"
SelectedValue="{Binding SelectedValue, Mode=TwoWay}"
DisplayMemberPath="Text" />
ViewModel:
public class MainWindowViewModel : ViewModel
{
public MainWindowViewModel()
{
Items = new ObservableCollection<Item>()
{
new Item() {Id ="1", Text = "Text 1" },
new Item() {Id ="2", Text = "Text 2" },
};
SelectedValue = "3";
}
private ObservableCollection<Item> items;
public ObservableCollection<Item> Items
{
get { return items; }
set { items = value; OnPropertyChanged(); }
}
private string selectedValue;
public string SelectedValue
{
get { return selectedValue; }
set { selectedValue = value; OnPropertyChanged(); }
}
}
public class Item
{
public string Id { get; set; }
public string Text { get; set; }
}
Upvotes: 2
Views: 226
Reputation: 169270
This logic should be implemented in the view model, i.e. you should never set the SelectedValue
to 3 when there is no such item in Items
. Then you set your view model into an invalid state.
So instead of trying to implement this kind of logic in the view or the control you should implement it in the view model where it belongs. It should be very simple:
SelectedValue = "3";
if (!Items.Any(x => x.Id == SelectedValue))
SelectedValue = null;
Or in the setter:
public string SelectedValue
{
get { return selectedValue; }
set
{
selectedValue = value;
if (!Items.Any(x => x.Id == SelectedValue))
selectedValue = null;
OnPropertyChanged();
}
}
Upvotes: 4