1

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

Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21
pinguinone
  • 433
  • 1
  • 6
  • 14
  • Does this answer your question? [Binding to display name attribute of enum in xaml](https://stackoverflow.com/questions/28671828/binding-to-display-name-attribute-of-enum-in-xaml) – Tatranskymedved Apr 22 '23 at 14:33
  • Also this https://stackoverflow.com/questions/3985876/wpf-binding-a-listbox-to-an-enum-displaying-the-description-attribute – Tatranskymedved Apr 22 '23 at 14:34
  • Thanks for your answer @Tatranskymedved but I try the last hour to folloq this answer your provide me with no success...can you elaborate e make for me some example code starting from my own? – pinguinone Apr 22 '23 at 15:45
  • this is the answer that does exactly what you want https://stackoverflow.com/a/12430331/7167572 – Tatranskymedved Apr 22 '23 at 17:09
  • @Tatranskymedved good and very elegant solution but I try and it doens't work...it display everything blank...I try after the Andrew Keepcofing (less elegant but very good) and it function! – pinguinone Apr 24 '23 at 07:21

1 Answers1

2

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>
Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21
  • Thanks so much! It works like a charm! The best thing at all could be to delete the datatemplate and the ViewsMode property for the ItemSource as done in link into another comment but it works very good also in that way. Thanks so much – pinguinone Apr 24 '23 at 07:24