Matt McManis
Matt McManis

Reputation: 4675

Changing Bound ComboBox Items

I want to expand on my previous question Pass ComboBox Selected Item as Method Parameter

Answer https://stackoverflow.com/a/45703484/6806643


I have a ComboBox bound to a List of items.

I'd like when a button is pressed to change the ComboBox to a different List of items.

From: Red, Orange Yellow, Green, Blue, Purple
To: Cyan, Magenta, Yellow, Black

The items set when the program starts. Inside the Change Button I add the new Colors to the _myComboItems List, but how to get it to set again when pressing the button?

Program


XAML

<Window x:Class="MyProgram.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyProgram"
        mc:Ignorable="d"
        Title="MainWindow" Height="289" Width="525">

    <Grid>
        <ComboBox x:Name="comboBox" 
                  DisplayMemberPath="Name"
                  ItemsSource="{Binding MyComboItems}"
                  SelectedItem="{Binding SelectedComboItem}"
                  SelectedIndex="0"
                  HorizontalAlignment="Left" 
                  Margin="264,88,0,0" 
                  VerticalAlignment="Top" 
                  Width="120"/>

        <Button x:Name="buttonChange" 
                Content="Change" 
                HorizontalAlignment="Left" 
                Margin="142,88,0,0" 
                VerticalAlignment="Top" 
                Width="75" 
                Click="button1_Click"/>
    </Grid>
</Window>

C#

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = this;

        SelectedComboItem = MyComboItems[0];
    }


    // ComboBox Items
    //
    private List<ComboItem> _myComboItems = new List<ComboItem>()
    {
      new ComboItem("Red"),
      new ComboItem("Orange"),
      new ComboItem("Yellow"),
      new ComboItem("Green"),
      new ComboItem("Blue"),
      new ComboItem("Purple")
    };

    public List<ComboItem> MyComboItems
    {
        get { return _myComboItems; }
    }


    // Property Changed
    //
    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }


    // Selected Item
    //
    private ComboItem _selected = null;
    public ComboItem SelectedComboItem
    {
        get { return _selected; }
        set
        {
            _selected = value;
            OnPropertyChanged("SelectedComboItem");
        }
    }


    // Change ComboBox Items
    //
    private void buttonChange_Click(object sender, RoutedEventArgs e)
    {
        // Change Items Here
    }
}



public class ComboItem
{
    public string Name { get; private set; }

    public ComboItem(string color)
    {
        Name = color;
    }
}

Upvotes: 0

Views: 85

Answers (1)

mm8
mm8

Reputation: 169200

You could either create a new List<ComboItem> and raise the PropertyChanged event for the MyComboItems property. Note that your class must also actually implement the INotifyPropertyChanged interface:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = this;

        SelectedComboItem = MyComboItems[0];
    }

    private List<ComboItem> _myComboItems = new List<ComboItem>()
    {
      new ComboItem("Red"),
      new ComboItem("Orange"),
      new ComboItem("Yellow"),
      new ComboItem("Green"),
      new ComboItem("Blue"),
      new ComboItem("Purple")
    };

    public List<ComboItem> MyComboItems
    {
        get { return _myComboItems; }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private ComboItem _selected = null;
    public ComboItem SelectedComboItem
    {
        get { return _selected; }
        set
        {
            _selected = value;
            OnPropertyChanged("SelectedComboItem");
        }
    }


    private void buttonChange_Click(object sender, RoutedEventArgs e)
    {
        // Change Items Here
        _myComboItems = new List<ComboItem>()
        {
            new ComboItem("Cyan"),
            new ComboItem("Magenta"),
            new ComboItem("Magenta"),
            new ComboItem("Black"),
        };
        OnPropertyChanged("MyComboItems");
        SelectedComboItem = MyComboItems[0];
    }
}

Another option would be to replace the List<ComboItem> with an ObservableCollection<ComboItem> and simply remove and add items to this one:

private ObservableCollection<ComboItem> _myComboItems = new ObservableCollection<ComboItem>()
{
    new ComboItem("Red"),
    new ComboItem("Orange"),
    new ComboItem("Yellow"),
    new ComboItem("Green"),
    new ComboItem("Blue"),
    new ComboItem("Purple")
};

public ObservableCollection<ComboItem> MyComboItems
{
    get { return _myComboItems; }
}

private void buttonChange_Click(object sender, RoutedEventArgs e)
{
    _myComboItems.Clear();
    _myComboItems.Add(new ComboItem("Cyan"));
    _myComboItems.Add(new ComboItem("Magenta"));
    _myComboItems.Add(new ComboItem("Magenta"));
    _myComboItems.Add(new ComboItem("Black"));
    SelectedComboItem = MyComboItems[0];
}

The difference between the two collection types is that the latter implements the INotifyCollectionChanged interface.

Upvotes: 2

Related Questions