0
votes

I want to bind a list of items with properties 'ID', 'Description' and 'IsSelected' to a combobox. The display value is set using DisplayMemberPath to 'Description' which works fine. However i want that 'IsSelected' property to be set when that item is selected. I've tried Setting SelectedValuePath and SelectedValue to 'IsSelected' but it doesn't work.

3
The Item is selected (not its ID or Description).paparazzo

3 Answers

0
votes

The simplest solution would probably be to track the selected item in your view model, and keep it synced with the ComboBox by adding a two-way binding to SelectedItem. When the view model property changes, update the IsSelected property of the new and previous selections.

1
votes

Nothing like re-answering a five year old question... I disagree with Mike in that you should keep track of both states as the ComboBox can give you the IsSelected state of the SelectedValue. Matrix was on the right lines but you can't use IsSelected with DisplayMemberPath.

With the code below my Fruits Selected property is bound to IsSelected.

View Code

<ComboBox ItemsSource="{Binding Fruit}"
          SelectedValue="{Binding SelectedFruitViewModel}" 
          DisplayMemberPath="Name">
    <ComboBox.ItemContainerStyle>
        <Style TargetType="ComboBoxItem">
            <Setter Property="IsSelected" Value="{Binding Selected}" />
        </Style>
    </ComboBox.ItemContainerStyle>
</ComboBox>

MainWindowViewModel

public class MainWindowViewModel : BaseViewModel
{
    private FruitViewModel _selectedFruitViewModel;

    public MainWindowViewModel()
    {
        this.Fruit = new ObservableCollection<FruitViewModel>
        {
            new FruitViewModel { Name = "Pineapple", Selected = false },
            new FruitViewModel { Name = "Apple", Selected = false },
            new FruitViewModel { Name = "Orange", Selected = false },
            new FruitViewModel { Name = "Kiwi", Selected = false }
        };
    }

    public ObservableCollection<FruitViewModel> Fruit { get; }

    public FruitViewModel SelectedFruitViewModel
    {
        get => _selectedFruitViewModel;
        set => SetProperty(ref _selectedFruitViewModel, value);
    }
}

FruitViewModel

public class FruitViewModel : BaseViewModel
{
    private bool _selected;
    private string _name;

    public bool Selected
    {
        get => _selected;
        set => SetProperty(ref _selected, value);
    }

    public string Name
    {
        get => _name;
        set => SetProperty(ref _name, value);
    }
}

BaseViewModel

public class BaseViewModel : INotifyPropertyChanged 
{
    public virtual event PropertyChangedEventHandler PropertyChanged;

    protected virtual bool SetProperty<T>(ref T storage, 
                                          T value, 
                                          [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(storage, value))
        {
            return false;
        }

        storage = value;

        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

        return true;
    } 
}
-1
votes

Try this

    <ComboBox Width="120" Height="35">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <ComboBoxItem IsSelected="{Binding IsSelected}"/>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>