Change a Combobox's selectedIndex from ViewModel and when the Combobox is binded

375 Views Asked by At

I want to have the selected index of a combobox change based on code from the ViewModel. Is this possible?

This is how my combobox is set up:

<ComboBox x:Name="cmbModels" DisplayMemberPath="ModelItemTextbox"
          SelectedItem="ItemNameTextbox" SelectionChanged="ModelSelectionChange" 
          ItemsSource="{Binding ModelComboList}">
</ComboBox>

Something else, my bindings don't work unless I have the SelectedItem set to "ItemNameTextbox". The Combobox is binded to an observableCollection.

private ObservableCollection<ModelComboListModel> _modelcombolist = new ObservableCollection<ModelComboListModel>();
    public ObservableCollection<ModelComboListModel> ModelComboList
    {
        get { return _modelcombolist; }
        set
        {
            _modelcombolist = value;
            OnPropertyChanged("ModelComboList");
        }
    }

And the class:

public class ModelComboListModel
{

    public string ItemName { get; set; }
    public string ItemId { get; set; }

    //public override string ToString()
    //{
    //    return $"ID:{ModelItemId} | {ModelItemName}";
    //}

    public string ItemTextbox
    {
        get
        {
            return $"{ ItemId }: {ItemName}";
        }
    }

}

The list just contains items and their id's.

Is there a good trick for changing the selectedindex from the ViewModel? I can't find anything useful on google or here :(

1

There are 1 best solutions below

1
dmedine On

You probably want to bind to the SelectedIndex property in your ComboBox. Then you can be strategic with your gets and sets in the view model to get the behavior you are looking for. In this example I made a TextBox that can be used to change the index of the ComboBox:

<StackPanel>
    <ComboBox x:Name="cmbModels" 
      SelectedItem="{Binding SelectedItem, Mode=OneWay}"
      SelectedIndex="{Binding SelectedItemIndex}"
      ItemsSource="{Binding ModelComboList}"
              Margin="5">
    </ComboBox>
    <TextBox Text="{Binding ItemSelect}"
               Margin="5"/>
</StackPanel>

View Model:

internal class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChangedEventHandler? handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private int _selectedItemIndex = 0;
    public int SelectedItemIndex
    {
        get => _selectedItemIndex;
        set
        {
            _selectedItemIndex = value;
            OnPropertyChanged();
        }
    }
    public ObservableCollection<string> ModelComboList { get; } = new() { "Item", "Foo", "Bar" };// populate with more items as needed

    public string SelectedItem => ModelComboList[_selectedItemIndex];

    public string ItemSelect
    {
        get => _selectedItemIndex.ToString();
        set
        {
            if (int.Parse(value) < 0 || int.Parse(value) > ModelComboList.Count)
                SelectedItemIndex = 0;
            else
                SelectedItemIndex = int.Parse(value);
        }
    }