code it

Martins Tech Blog

Flagged Enums und XAML-Syntax

In meinem letzten Post habe ich mich mit den Besonderheiten der XAML-Syntax bei Nested Types auseinandergesetzt. Ähnlich gewöhnungsbedürftig ist die Syntax bei Flagged Enums.

Standard-Enum-Werte können mit Hilfe der Textrepräsentation recht einfach zugewiesen werden. Ein Beispiel dafür ist die Eigenschaft Visibility.

<TextBlock Text="Sampletext" Visibility="Collapsed" />

Hier sorgt der TypeConverter für Enums dafür, dass aus dem String "Collapsed"  der Wert System.Windows.Visibility.Collapsed generiert wird.

Etwas anders sieht das Ganze bei Flagged Enums aus. Als Beispiel soll ein UserControl dienen, an dem per DependencyProperty eingestellt werden kann, welche Eingabemethoden gültig sind. Da hier mehrere Werte möglich sind, wird das Ganze über ein Flagged Enum gelöst.

Mehr...

Nested Types und XAML-Syntax

Ich gebe zu, ich bin kein großer Freund von Nested Types, da sie an einigen Stellen umständlicher zu behandeln sind als Typen, die "ganz normal" in Namespaces liegen. Aber es soll API-Hersteller geben, die Nested Types verwenden. Um dann nicht Dinge mehrfach entwickeln zu müssen, bietet es sich an, diese Typen gleich weiterzuverwenden.

Was ist ein Nested Type?

Das ist recht einfach erklärt: Ein Nested Type ist ein Datentyp, der in einem anderen Datentyp deklariert ist - also eine Klassendefinition innerhalb einer anderen Klasse und eben nicht direkt in einem Namespace. Das folgende Beispiel soll das etwas verdeutlichen:

public class Constants
{
    public class Colors
    {
        public const string Red = "#FF0000";
        public const string Green = "#00FF00";
        public const string Blue = "#0000FF";
    }

    public class Alignments
    {
        public const string Left = "Left";
        public const string Right = "Right";
    }
}

Zugriff im Code

Der Zugriff im Code ist ähnlich wie wenn die Klasse in einem Namespace liegt - man verwendet die Punkt-Syntax.

var color = Constants.Colors.Blue;

Zu beachten ist hier lediglich, dass man sich ab dem obersten Typ durch die Struktur hangeln muss und eben nicht wie im Fall von Namespaces eine using-Direktive verwenden kann. Ok, einen Trick gibt es doch - man kann einen Alias für den Typ vergeben:

using ColorConstants = Constants.Colors;

public class MainViewModel
{
    public MainViewModel()
    {
        LoadData();
    }

    public void LoadData()
    {
        var color = ColorConstants.Blue;
    }
}

Zugriff im XAML

In meinem Beispiel handelt es sich um Konstanten, auf die ich im XAML auch gern im statischen Kontext zugreifen möchte . Dafür bietet sich x:Static an. Verwende ich hier die gleiche Syntax wie im Code, so erhalte ich eine Fehlermeldung die besagt, dass der Typ nicht gefunden werden kann.

Alles kein Problem - dabei handelt es sich nämlich um einen Syntaxfehler. Der Zugriff auf Nested Types erfolgt nicht mit "." sondern mit "+". Korrekt ist es also wie folgt:

<TextBlock Text="{x:Static local:Constants+Colors.Blue}" />

Damit funktioniert der Zugriff nun zur Laufzeit, und auch in Expression Blend wird alles korrekt angezeigt. Aber ab diesem Zeitpunkt streikt nun der Designer von Visual Studio.

Englische Version Englische Version