Bruno V
Bruno V

Reputation: 1731

Clear the SelectedValue from a ComboBox automatically when it is not part of the ItemsSource

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

Answers (1)

mm8
mm8

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

Related Questions