Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding to display name attribute of enum in xaml

Tags:

c#

enums

wpf

xaml

I have the following enum:

public enum ViewMode
{
    [Display(Name = "Neu")]
    New,
    [Display(Name = "Bearbeiten")]
    Edit,
    [Display(Name = "Suchen")]
    Search
}

I'm using xaml and databinding to show the enum in my window:

<Label Content="{Binding CurrentViewModel.ViewMode}" Grid.Column="2" VerticalContentAlignment="Bottom" Height="43" HorizontalContentAlignment="Right"/>

But this doesn't show the display name attribute. How can I do so?

In my viewModel I can get the display name attribute by using an extension method:

public static class EnumHelper
{
    /// <summary>
    /// Gets an attribute on an enum field value
    /// </summary>
    /// <typeparam name="T">The type of the attribute you want to retrieve</typeparam>
    /// <param name="enumVal">The enum value</param>
    /// <returns>The attribute of type T that exists on the enum value</returns>
    public static T GetAttributeOfType<T>(this Enum enumVal) where T : System.Attribute
    {
        var type = enumVal.GetType();
        var memInfo = type.GetMember(enumVal.ToString());
        var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
        return (attributes.Length > 0) ? (T)attributes[0] : null;
    }
}

Usage is string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description;. However, this doesn't help in XAML.

like image 229
mosquito87 Avatar asked Feb 23 '15 10:02

mosquito87


People also ask

How to display all items from an enum in MVVM WPF?

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:

Is it possible to bind an enum?

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’).

What is data binding in XAML?

XAML - Data Binding. Data binding is a mechanism in XAML applications that provides a simple and easy way for Windows Runtime Apps using partial classes to display and interact with data. The management of data is entirely separated from the way the data is displayed in this mechanism.

How do I bind to an enumeration?

This example shows how to bind to an enumeration. Unfortunately there isn't a direct way to use an enumeration as a data binding source. However, the Enum.GetValues (Type) method returns a collection of values. These values can be wrapped in an ObjectDataProvider and used as a data source.


1 Answers

Create a class implementing the System.Windows.Data.IValueConverter interface and specify it as the binding's converter. Optionally, for easier usage, you can create a "provider" class implementing System.Windows.Markup.MarkupExtension (actually you can do both with just one class). Your end result could resemble this example:

public class MyConverter : MarkupExtension, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((Enum)value).GetAttributeOfType<DisplayAttribute>().Name;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

And then in XAML:

<Label Content="{Binding CurrentViewModel.ViewMode, Converter={local:MyConverter}}" Grid.Column="2" VerticalContentAlignment="Bottom" Height="43" HorizontalContentAlignment="Right"/>
like image 92
Grx70 Avatar answered Nov 05 '22 23:11

Grx70