Hello Devz,
In my two previous posts, I was talking about how to bind an enum (the classic way and the other way). But these have two major issues. First, all the items from the Enum will be bound and displayed. And sometimes you don’t want to display all of them (like ‘None’). Secondly, you will probably prefer to display the description attribute of the Enum instead of the Enum itself in your MVVM WPF application.
Here is the Enum we will use in our example:
using System.ComponentModel; namespace EnumBindingWithDescription { public enum StatusEnum { [Description("No status yet")] None = 0, [Description("Waiting to run")] Waiting = 1, [Description("Run in progress")] Running = 2, [Description("Paused by user")] Paused = 3, [Description("Run is a success")] Success = 4, [Description("Run finished with error")] Failure = 5 } }
Now to display our description, we will use a Converter with IValueConverter:
using System; using System.ComponentModel; using System.Globalization; using System.Reflection; using System.Windows.Data; namespace EnumBindingWithDescription { public class EnumDescriptionConverter : IValueConverter { private string GetEnumDescription(Enum enumObj) { FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString()); object[] attribArray = fieldInfo.GetCustomAttributes(false); if (attribArray.Length == 0) return enumObj.ToString(); else { DescriptionAttribute attrib = null; foreach (var att in attribArray) { if (att is DescriptionAttribute) attrib = att as DescriptionAttribute; } if (attrib != null) return attrib.Description; return enumObj.ToString(); } } object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) { Enum myEnum = (Enum)value; string description = GetEnumDescription(myEnum); return description; } object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return string.Empty; } } }
Here is our XAML View displaying the ComboBox with the bound Enum:
<Window x:Class="EnumBindingWithDescription.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" xmlns:local="clr-namespace:EnumBindingWithDescription" Title="{Binding Title}" Height="350" Width="525"> <Window.Resources> <local:EnumDescriptionConverter x:Key="enumConverter" /> </Window.Resources> <Grid> <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center"> <!--DISPLAY THE COMBOBOX WITH OUR SELECTED ENUMS--> <ComboBox Height="25" Width="200" Margin="5" ItemsSource="{Binding Statuses}" SelectedItem="{Binding SelectedStatus}"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Converter={StaticResource enumConverter}}"/> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> <!--DISPLAY THE RESULT OF THE SELECTION--> <Label Height="25" Width="200" Content="{Binding Result}" Margin="5"/> </StackPanel> </Grid> </Window>
And finally our ViewModel:
using Prism.Mvvm; using System.Collections.Generic; using System.Linq; namespace EnumBindingWithDescription.ViewModels { public class MainWindowViewModel : BindableBase { #region Properties private string _title = "Enum Binding With Description"; public string Title { get { return _title; } set { SetProperty(ref _title, value); } } private List<StatusEnum> _statuses; public List<StatusEnum> Statuses { get { return _statuses; } set { SetProperty(ref _statuses, value); } } private StatusEnum _selectedStatus; public StatusEnum SelectedStatus { get { return _selectedStatus; } set { SetProperty(ref _selectedStatus, value); this.OnSelectedStatusChanged(); } } private string _result; public string Result { get { return _result; } set { SetProperty(ref _result, value); } } #endregion public MainWindowViewModel() { this.Statuses = new List<StatusEnum> { StatusEnum.Waiting, StatusEnum.Running, StatusEnum.Paused, StatusEnum.Success, StatusEnum.Failure }; if (this.Statuses.Any()) this.SelectedStatus = this.Statuses.First(); } private void OnSelectedStatusChanged() { var msg = $"This is the selected Status: {this.SelectedStatus}"; this.Result = msg; } } }
As you can see, this method is quite simple and have all the advantages compare to the other solutions.
Happy binding! 🙂
[…] PreviousNext […]