kar
kar

Reputation: 3651

Using a combobox1 to determine the values to be displayed on the second combobox2

I have 2 combo boxes. I want to set it up such that when the user chooses an information on the first combo box, that would determine what is to be displayed on the second combobox.

For example combobox1 has 2 listboxitems:
Fruit
Cars

If Fruit is selected on first combobox, the second combobox will display listboxes:

Apple
Orange

If Cars is selected on first combobox, the second combobox will display listboxes:

Honda
Nissan

Is there a way to do this?

<ComboBox Name="comboBox1" Canvas.Left="74" Canvas.Top="527" Width="120">
                <ListBoxItem Content="Fruit"/>
                <ListBoxItem Content="Car"/>
            </ComboBox>

<ComboBox Name="comboBox2" Canvas.Left="74" Canvas.Top="527" Width="120">
                <ListBoxItem Content="Apple"/>
                <ListBoxItem Content="Orange"/>

                <ListBoxItem Content="Honda"/>
                <ListBoxItem Content="Nissan"/>
            </ComboBox>

Upvotes: 0

Views: 75

Answers (2)

d.moncada
d.moncada

Reputation: 17402

Okay, here's a quick example using DataBinding and an associated ViewModel.

The ViewModel is used to hold the list of ItemTypes, and Items. Using DataBinding, the ComboBox ItemsSource is bound to the applicable public properties. Whenever a new ItemType is selected, the Items list is then filtered.

Xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:converters="clr-namespace:WpfApplication1"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <ComboBox Name="comboBox1" Width="120" Margin="0,25,0,50" ItemsSource="{Binding Types}" SelectedItem="{Binding SelectedType}"/>
        <ComboBox Name="comboBox2" Width="120" ItemsSource="{Binding Items}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Value}"/>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </StackPanel>
</Window>

Xaml.cs:

This is used to set the DataContext of the Window to the ViewModel. There are other ways, but this is the simplest for sake of demonstration.

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    MainViewModel vm = new MainViewModel();
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = vm;
    }
}

ViewModel:

This is where all the logic lives in terms of data, filtering, etc. NotifyPropertyChanged is an event that needs to be raised whenever a bound property changes so that it can notify the control of the update.

namespace WpfApplication1
{
    public class MainViewModel : INotifyPropertyChanged
    {
        #region Members
        private ItemType _selectedType;
        private List<Item> _allItems;
        private List<Item> _items;
        #endregion Members

        #region Properties
        /// <summary>
        /// Gets or sets the Selected Item Type
        /// </summary>
        /// <value>
        /// The selected Item Type
        /// </value>
        public ItemType SelectedType
        {
            get { return _selectedType; }
            set
            {
                _selectedType = value;
                Filter(); // Filter items list once SelectedType has changed
            }
        }

        /// <summary>
        /// Gets a list of all Item Types
        /// </summary>
        public List<ItemType> Types { get; private set; }

        /// <summary>
        /// Gets or sets the currently filltered list of Items
        /// </summary>
        /// <value>
        /// The fitlered items.
        /// </value>
        public List<Item> Items 
        {
            get { return _items; }
            set
            {
                _items = value;
                NotifyPropertyChanged("Items");
            }
        }
        #endregion Properties

        public MainViewModel()
        {
            Types = new List<ItemType>
            {
                ItemType.All,
                ItemType.Fruit,
                ItemType.Car
            };

            _allItems = new List<Item>
            {
                new Item
                {
                    Value = "Apple",
                    Type = ItemType.Fruit
                },
                new Item
                {
                    Value = "Orange",
                    Type = ItemType.Fruit
                },
                new Item
                {
                    Value = "Honda",
                    Type = ItemType.Car
                },
                new Item
                {
                    Value = "Nissan",
                    Type = ItemType.Car
                }
            };
            Items = _allItems;
        }

        /// <summary>
        /// Filters the Items list based on currently selected Item Type
        /// </summary>
        private void Filter()
        {
             var filteredItems = new List<Item>();
             if (ItemType.All == _selectedType)
             {
                 filteredItems = _allItems;
             }
             else 
             {
                 foreach (var item in _allItems)
                 {
                     if (item.Type == _selectedType)
                     {
                         filteredItems.Add(item);
                     }
                 }
             }
             Items = filteredItems;
        }

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }

    public enum ItemType
    {
        All,
        Fruit,
        Car
    }

    public class Item
    {
        public string Value { get; set; }
        public ItemType Type { get; set; }
    }
}

Upvotes: 1

user3477273
user3477273

Reputation:

You could create a collection for every set (cars and fruits) and then clear the combo box and add the collection into it depending the object you selected

Upvotes: 0

Related Questions