pinguinone
pinguinone

Reputation: 473

WinUI 3 - Bind a combobox to a enum and display the Display property

I don't figure out a solution for a clean and resuable code for bind a enum to a combobox in WinUi 3.

I have a general class that holds all the enum of my projects and in that I have this code:

    public class Enums
    {
        public enum ViewMode
        {
            [Display(Name = "Come nel dispositivo")]
            AsDevice,
            [Display(Name = "Chiaro")]
            Light,
            [Display(Name = "Scuro")]
            Dark
        }
    }

In the ViewModel file I have this code:

private IList<Enums.ViewMode> _viewsMode = Enum.GetValues(typeof(Enums.ViewMode)).Cast<Enums.ViewMode>().ToList();

public IList<Enums.ViewMode> ViewsMode => _viewsMode;
public Enums.ViewMode ViewMode
{
    get { return _model.ViewMode; }
    set
    {
        if (_model.ViewMode != value)
        {
           _model.ViewMode = value;
           RaisePropertyChanged();
           UpdateCommand.RaiseCanExecuteChanged();
         }
     }
}

Finally in the xaml file I have this code:

<ComboBox Width="160" ItemsSource="{x:Bind ViewModel.ViewsMode}" SelectedItem="{x:Bind ViewModel.ViewMode,Mode=TwoWay}"/>

And so far so good, it works perfectly. but it display "AsDevice" or "Light" or "Dark" while I want to display the DisplayName property as "Come nel dispositivo" or "Chiaro" or "Scuro", How can I do that? Thanks to everyone

Upvotes: 3

Views: 1501

Answers (1)

Andrew KeepCoding
Andrew KeepCoding

Reputation: 13666

You can do this with a ValueConverter:

public class EnumToDisplayNameConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return value is Enum enumValue &&
            enumValue.GetType()
                .GetMember(enumValue.ToString())
                .FirstOrDefault()
                    ?.GetCustomAttribute<DisplayAttribute>()
                    ?.GetName() is string displayName
                        ? displayName
                        : $"Unknow value: {value}";
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

and use it like this:

<Page
    x:Class="EnumDisplayNameExample.MainPage"
    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:local="using:EnumDisplayNameExample"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    mc:Ignorable="d">
    <Page.Resources>
        <local:ViewModel x:Name="ViewModel" />
        <local:EnumToDisplayNameConverter x:Key="EnumToDisplayNameConverter" />
    </Page.Resources>

    <StackPanel>
        <ComboBox
            Width="160"
            ItemsSource="{x:Bind ViewModel.ViewsMode}"
            SelectedItem="{x:Bind ViewModel.ViewMode, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Converter={StaticResource EnumToDisplayNameConverter}}" />
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
        <TextBlock Text="{x:Bind ViewModel.ViewMode, Mode=OneWay, Converter={StaticResource EnumToDisplayNameConverter}}" />
    </StackPanel>

</Page>

Upvotes: 4

Related Questions