WPF, Silverlight, Windows Phone 8 und Windows-Store-Apps

WPF: Data-Binding von Enums
Kommentare

In der Kolumne „XAML Expertise“ präsentiert Gregor Biswanger Top-How-tos zum Thema XAML. Einsteiger und fortgeschrittene XAML-Experten sollen hier durch geballtes Wissen gesättigt werden. Heute gibt es folgende Expertise: „WPF: Data Binding von Enums“. 

Das Verwenden von Enum-Daten unter XAML erweist sich in der Praxis als nicht gerade schmackhaft. Der Grund dafür ist der zusätzliche Aufwand, der für das Data Binding benötigt wird. Statt direkt über das ViewModel zu gehen, muss man einen Umweg über den zusätzlichen ObjectDataProvider einschlagen.

Markup Extension schreiben

Einen angenehmeren Weg zeigt eine selbst geschriebene Markup Extension, die das Standard-XAML um die gewünschte Enum-Unterstützung erweitert. So reicht eine zusätzliche Binding-Deklaration von EnumBindingSource aus, um das Data Binding mit Enums zum Laufen zu bringen. Der Code dazu findet sich in Listing 1. Ein einfaches Beispiel mit einem ViewModel zeigen die Listings 2 und 3.

public class EnumBindingSourceExtension : MarkupExtension
{
  private Type _enumType;
  public Type EnumType
  {
    get { return _enumType; }
    set
    {
        if (value != _enumType)
        {
            if (null != value)
            {
                Type enumType = Nullable.GetUnderlyingType(value) ?? value;

                if (!enumType.IsEnum)
                    throw new ArgumentException("Type must be for an Enum.");
            }

            _enumType = value;
        }
    }
  }

  public EnumBindingSourceExtension() { }

  public EnumBindingSourceExtension(Type enumType)
  {
    EnumType = enumType;
  }

  public override object ProvideValue(IServiceProvider serviceProvider)
  {
    if (null == _enumType)
        throw new InvalidOperationException("The EnumType must be specified.");

    Type actualEnumType = Nullable.GetUnderlyingType(_enumType) ?? _enumType;
    Array enumValues = Enum.GetValues(actualEnumType);

    if (actualEnumType == _enumType)
        return enumValues;

    Array tempArray = Array.CreateInstance(actualEnumType, enumValues.Length + 1);
    enumValues.CopyTo(tempArray, 1);
    return tempArray;
  }
}
 
public class MainWindowViewModel
{
  public State NetworkState { get; set; }
}

public enum State
{
  Online,
  Offline
}
 
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:viewModels="clr-namespace:EnumBindingSample.ViewModels"
  xmlns:extensions="clr-namespace:EnumBindingSample.Common.Extensions"
  Title="MainWindow" Height="350" Width="525">
    
      
    

    
      
    

 
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -