Add items to WPF combobox dynamically and later reset the value on some event

16,767

Here is how you would do this with a more MVVM approach:

ViewModel:

public class MyViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public Location SelectedcbDefaultLocationListItem = new Location { LocationName = "---Select One---", LocationID = -1 };

    public ObservableCollection<Location> LocationList { get; set; }

    private int _selectedLocationID;

    /// <summary>
    /// Get/Set the SelectedLocationID property. Raises property changed event.
    /// </summary>
    public int SelectedLocationID
    {
        get { return _selectedLocationID; }
        set
        {
            if (_selectedLocationID != value)
            {
                _selectedLocationID = value;

                RaisePropertyChanged("SelectedLocationID");
            }
        }
    }        

    /// <summary>
    /// Constructor
    /// </summary>
    public MyViewModel()
    {
        LocationList = new ObservableCollection<Location>();
        LocationList.Add(new Location() { LocationID = 1, LocationName = "Here" });
        LocationList.Add(new Location() { LocationID = 2, LocationName = "There" });

        LocationList.Insert(0, SelectedcbDefaultLocationListItem);

        SelectedLocationID = SelectedcbDefaultLocationListItem.LocationID;
    }

    /// <summary>
    /// Resets the selection to the default item.
    /// </summary>
    public void ResetSelectedItem()
    {
        SelectedLocationID = SelectedcbDefaultLocationListItem.LocationID;
    }

    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }   
}

Code Behind:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow
{
    public MyViewModel ViewModel { get; private set; }

    public MainWindow()
    {
        InitializeComponent();

        ViewModel = new MyViewModel();

        DataContext = ViewModel;
    }

    private void ResetButton_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        ViewModel.ResetSelectedItem();
    }
}

XAML:

<Window xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"  x:Class="StackOverflow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel>
            <ComboBox ItemsSource="{Binding LocationList, Mode=OneWay}" DisplayMemberPath="LocationName" SelectedValuePath="LocationID" SelectedValue="{Binding SelectedLocationID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            <Button Click="ResetButton_Click" Content="Reset" Margin="5" HorizontalAlignment="Right" />
        </StackPanel>        
    </Grid>    
</Window>

Normally a command would be used instead of calling the reset method in the code behind. But since you aren't using a full MVVM approach this should suffice.

Share:
16,767
Saket
Author by

Saket

Working as a freelancer.

Updated on August 21, 2022

Comments

  • Saket
    Saket over 1 year

    I am new to WPF but I searched a lot and in the end decided to seek help from you guys...

    I have a class - Location With primary properties as -

    LocationName

    LocationID

    I wish to bind this class to a combo box in WPF. I fetch the location list from database. I need to display the list in the combobox with the first text / value pair as ---Select One--- / -1. Now, so far I have done this -

    create -

    public ObservableCollection<ComboBoxItem> cbLocationList { get; set; }
    
    cbLocationList = new ObservableCollection<ComboBoxItem>();
    
    SelectedcbDefaultLocationListItem = new ComboBoxItem { Content = "---Select One---" , Tag="-1"};
    
    cbLocationList.Add(SelectedcbDefaultLocationListItem);
    

    Fill the items in a loop as -

    foreach (Location loc in LocationtList)
    {
    
     cbLocationList.Add(new ComboBoxItem  { Content = loc.LocationName, Tag=loc.LocationID.ToString() });
    
    }
    

    where I set the cbLocationList in XAML as -

    ItemsSource="{Binding cbLocationList}" 
    

    of the combobox. This works well, but on resetting the form I need to reset the value of the combo box to "-1". I am unable to do so with the tag property. (I searched, and it seems we dont have a value property like in the ListItem) Every body seems to suggest I bind it with a class and set the DisplayMemberPath and SelectedValuePath. Now if I directly bind with my Location class, How do I insert the --Select One-- item. I could do that by creating a dummy object and insert it into my list before binding. But is this the best way to work in WPF. Maybe there is an altogether different approach which I am missing. Please advise.

    Thanks in advance. !