Using the ComboBox SelectedItem property in WPF / MVVM

An implementation of using the WPF Combo Box using MVVM patterns.

The intention is to get a ComboBox control’s SelectedItem property to bind to an instance of a selected object, so that when the SelectedItem is changed, all other entities that are bound to it are also updated. See this StackOverflow discussion for background information:

http://stackoverflow.com/questions/11062297/wpf-mvvm-combobox-selecteditem

Step 1: Create a new WPF project:

Step 2: Create your classes

In my example I use a ‘Languages’ class that holds a language value, such as “English” and another string to identify it, such as “en”:

Languages.cs

using System.ComponentModel;
using System.Runtime.CompilerServices;
using WpfComboBox.Annotations;

namespace WpfComboBox
{
    public class Language : INotifyPropertyChanged
    {
        private string _languageValue;
        private string _languageId;

        public string LanguageValue
        {
            get
            {
                return _languageValue;
            }
            set
            {
                _languageValue = value;
                OnPropertyChanged(nameof(LanguageValue));
            }
        }

        public string LanguageId
        {
            get
            {
                return _languageId;
            }
            set
            {
                _languageId = value;
                OnPropertyChanged(nameof(LanguageId));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

And also a ViewModel class:

MainWindowViewModel.cs

using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using WpfComboBox.Annotations;

namespace WpfComboBox
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        private Language _currentSelection;
        private string _labelText;

        public MainWindowViewModel()
        {
            CurrentSelection = Languages.First();
        }

        public List<Language> Languages { get; } = new List<Language>
        {
            new Language {LanguageValue = "English", LanguageId = "en"},
            new Language {LanguageValue = "German", LanguageId = "de"},
            new Language {LanguageValue = "Italian", LanguageId = "it"}
        };

        public Language CurrentSelection
        {
            get { return _currentSelection; }
            set
            {
                _currentSelection = value;
                LabelText = "Current language selected: " + _currentSelection.LanguageValue;
                OnPropertyChanged(nameof(CurrentSelection));
            }
        }

        public string LabelText
        {
            get { return _labelText; }
            set
            {
                _labelText = value;
                OnPropertyChanged(nameof(LabelText));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Step 3: Create your XAML view

Update the MainWindow.xaml to create the window containing the ComboBox control, as well as a Label control to display the current
language being selected:

MainWindow.xaml

<Window x:Class="WpfComboBox.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:viewModel="clr-namespace:WpfComboBox"
        mc:Ignorable="d"
        Title="Language Selection Combo Box" Height="250" Width="325">

    <Window.DataContext>
        <viewModel:MainWindowViewModel />
    </Window.DataContext>

    <StackPanel
        Width="300"
        VerticalAlignment="Center">

        <Label
            Height="60"
            FontSize="14"
            VerticalContentAlignment="Center"
            Content="{Binding LabelText}" />

        <ComboBox
            Height="50"
            x:Name="LanguagesComboBox"
            FontSize="14"
            VerticalContentAlignment="Center"
            ItemsSource="{Binding Path=Languages}"
            DisplayMemberPath="LanguageValue"
            SelectedValuePath="LanguageValue"
            SelectedValue="{Binding CurrentSelection.LanguageValue}"
            SelectedItem="{Binding CurrentSelection}" />
    </StackPanel>

</Window>

Step 4: Try it out

For this very simple example that should be all there is to it.

On building and running the project notice the selected ComboBox item defaults to English”:

Notice that on selecting another language, the ComboBox control is populated with the list of languages that are initialsed in the MainWindowViewModel class:

And when we select another language, “Italian” for example, the dialog controls are updated accordingly:

Leave a Reply