Alice Guo
Alice Guo

Reputation: 35

How can I have a multi-column dropdown box in C# WPF?

I'm trying to create a multi-column combobox in c# wpf like below. Any Ideas?

enter image description here

When one row is selected, only the State code show up, but all detail could show up in the drop down selection.

Upvotes: 0

Views: 428

Answers (1)

Sach
Sach

Reputation: 10393

You can get a little creative and solve this problem. Say you have a combo box that's only 60px wide. So you want combo items to be displayed as the full state name and abbreviation, like CA - California, but if selected, you only want the abbr. CA.

I declare a class to represent a state like so:

public class State
{
    public string ShortName { get; set; }
    public string FullName { get; set; }
    private string _displayName;
    public string DisplayName
    {
        set
        {
            _displayName = value;
        }
        get
        {
            if (string.IsNullOrEmpty(_displayName))
                return string.Format("{0} - {1}", ShortName, FullName);
            else
                return _displayName;
        }
    }
}

The trick is that you use DisplayName to display items on the combo box. Then, in the get of DisplayName, if it already has a value, you return it, if not, you concatenate the short and full names of states.

Then when you do data binding, you have a list of states as well as a SelectedState, and in the setter of that property, you set the DisplayName to ShortName.

So, my XAML:

<Grid>
    <ComboBox ItemsSource="{Binding States}"
              SelectedValue="{Binding SelectedState}"
              DisplayMemberPath="DisplayName"
              Name="CmbStates" Width="60" Height="32"/>
</Grid>

Then, in my code:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

    private List<State> _states;
    public List<State> States
    {
        get { return _states; }
        set
        {
            _states = value;
            OnPropertyChanged("States");
        }
    }

    private State _selectedState;
    public State SelectedState
    {
        get { return _selectedState; }
        set
        {
            _selectedState = value;
            SelectedState.DisplayName = SelectedState.ShortName;
            OnPropertyChanged("SelectedState");
        }
    }

    public MainWindow()
    {
        InitializeComponent();
        States = new List<State>
        {
            new State() { FullName = "California", ShortName = "CA" },
            new State() { FullName = "New York", ShortName = "NY" },
            new State() { FullName = "Oregon", ShortName = "OR" }
        };
        DataContext = this;
    }
}

Now you should have the full concatenated name in the list:

enter image description here

But only the abbreviation when selected:

enter image description here

Upvotes: 3

Related Questions