TypeConverter und XAML

In diesem Thema wird der Zweck der Typkonvertierung aus einer Zeichenfolge in eine allgemeinere Funktion der XAML-Sprache erläutert. In .NET Framework dient die TypeConverter-Klasse als Teil der Implementierung für eine verwaltete benutzerdefinierte Klasse, die als Eigenschaftswert in der XAML-Attributverwendung verwendet werden kann, einem bestimmten Zweck. Wenn Sie eine benutzerdefinierte Klasse schreiben und Instanzen dieser Klasse als festlegbare XAML-Attributwerte verwendet werden sollen, müssen Sie möglicherweise TypeConverterAttribute auf die Klasse anwenden und/oder eine benutzerdefinierte TypeConverter-Klasse schreiben.

Typkonvertierungskonzepte

XAML- und Zeichenfolgenwerte

Wenn Sie einen Attributwert in einer XAML-Datei festlegen, ist der ursprüngliche Typ dieses Werts eine Zeichenfolge in reinem Text. Auch andere Primitive wie Double sind anfänglich Textzeichenfolgen für einen XAML-Prozessor.

Ein XAML-Prozessor benötigt zwei Angaben, um einen Attributwert zu verarbeiten. Die erste Angabe ist der Werttyp der Eigenschaft, die festgelegt wird. Jede Zeichenfolge, die einen Attributwert definiert, und in XAML verarbeitet wird, muss schließlich umgewandelt werden oder zu einem Wert dieses Typs aufgelöst werden. Wenn es sich beim Wert um einen Primitiv handelt, den der XAML-Parser versteht (beispielsweise ein numerischer Wert), wird versucht, eine direkte Konvertierung der Zeichenfolge vorzunehmen. Wenn es sich bei dem Wert um eine Enumeration handelt, wird mithilfe der Zeichenfolge nach einer Namensübereinstimmung mit einer benannten Konstante in dieser Enumeration gesucht. Wenn es sich beim Wert weder um einen primitiven Typ handelt, den der Parser versteht, noch um eine Enumeration, muss der zutreffende Typ einen Typ oder Wert bereitstellen können, der auf einer konvertierten Zeichenfolge beruht. Dies erfolgt durch Angabe einer Typkonverterklasse. Der Typkonverter ist eine Hilfsklasse zum Bereitstellen von Werten einer anderen Klasse im XAML-Szenario und möglicherweise auch für Codeaufrufe in .NET-Code.

Verwenden von vorhandenem Typkonvertierungsverhalten in XAML

Je nach Ihren Vorkenntnissen der zugrunde liegenden XAML-Konzepte verwenden Sie möglicherweise bereits das Typkonvertierungsverhalten in der grundlegenden XAML-Anwendung, ohne es zu wissen. WPF definiert z. B. buchstäblich Hunderte von Eigenschaften, die einen Wert vom Typ Point verwenden. Point ist ein Wert, der eine Koordinate in einem zweidimensionalen Koordinatenbereich beschreibt und nur zwei wichtige Eigenschaften aufweist: X und Y. Wenn Sie einen Punkt in XAML angeben, geben Sie ihn als Zeichenfolge mit einem Trennzeichen (in der Regel ein Komma) zwischen den von Ihnen angegebenen Werten X und Y an. Beispiel: <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"/>

Auch dieser einfache Typ von Point und dessen einfache Verwendung in XAML erfordern einen Typkonverter. In diesem Fall ist dies die Klasse PointConverter.

Der auf Klassenebene definierte Typkonverter für Point optimiert die Verwendungsmöglichkeiten von Markup von allen Eigenschaften, die Point annehmen. Ohne Typkonverter benötigen Sie das folgende, viel ausführlichere Markup für dasselbe zuvor gezeigte Beispiel:

<LinearGradientBrush>
  <LinearGradientBrush.StartPoint>
    <Point X="0" Y="0"/>
  </LinearGradientBrush.StartPoint>
  <LinearGradientBrush.EndPoint>
    <Point X="1" Y="1"/>
  </LinearGradientBrush.EndPoint>
</LinearGradientBrush>

Die Verwendung der Zeichenfolge für die Typkonvertierung oder die einer ausführlicheren entsprechenden Syntax ist eine Stilfrage beim Programmieren. Der XAML-Tool-Workflow könnte auch beeinflussen, wie Werte festgelegt werden. Einige XAML-Tools neigen dazu, die ausführlichste Form von Markup auszugeben, da ein Roundtrip zu Designeransichten oder zum eigenen Serialisierungsmechanismus einfacher ist.

Vorhandene Typkonverter können in der Regel für WPF- und .NET Framework-Typen ermittelt werden, indem eine Klasse (oder Eigenschaft) auf das angewendete TypeConverterAttribute-Element überprüft wird. Dieses Attribut benennt die Klasse, die den unterstützenden Typkonverter für Werte dieses Typs darstellt, für XAML-Zwecke sowie für mögliche andere Zwecke.

Typkonverter und Markuperweiterungen

Markuperweiterungen und Typkonverter füllen orthogonale Rollen in Bezug auf das Verhalten des XAML-Prozessors und die Szenarios, auf die sie auf angewendet werden. Obwohl der Kontext für die Verwendung von Markuperweiterungen verfügbar ist, wird das Typkonvertierungsverhalten von Eigenschaften, bei denen eine Markuperweiterung einen Wert bereitstellt, in der Regel nicht in den Implementierungen der Markuperweiterung überprüft. Anders ausgedrückt: Selbst wenn eine Markuperweiterung eine Textzeichenfolge als ProvideValue-Ausgabe zurückgibt, wird das Typkonvertierungsverhalten für diese Zeichenfolge, wie es auf eine bestimmte Eigenschaft oder einen Eigenschaftswerttyp angewendet wird, nicht aufgerufen. Im Allgemeinen besteht der Zweck einer Markuperweiterung darin, ohne Typkonverter eine Zeichenfolge zu verarbeiten und ein Objekt zurückzugeben.

Eine allgemeine Situation, in der eine Markuperweiterung statt einem Typkonverter erforderlich ist, besteht im Erstellen eines Verweises auf ein vorhandenes Objekt. Ein zustandsloser Typkonverter könnte bestenfalls nur eine neue Instanz genieren, die möglicherweise nicht gewünscht ist. Weitere Informationen über Markuperweiterungen finden Sie unter Markuperweiterungen und WPF XAML.

Systemeigene Typkonverter

In WPF- und .NET Framework-Implementierungen des XAML-Parsers gibt es bestimmte Typen, die über eine native Typkonvertierungsverarbeitung verfügen. Diese Typen werden jedoch herkömmlich nicht als primitive Typen angesehen. Ein Beispiel eines solchen Typs ist DateTime. Der Grund dafür basiert auf der Funktionsweise der .NET Framework-Architektur: Der Typ DateTime ist in „mscorlib“ definiert. Hierbei handelt es sich um die grundlegendste Bibliothek in .NET. Es ist nicht zulässig, DateTime mit einem Attribut zu versehen, das aus einer anderen Assembly stammt, wodurch eine Abhängigkeit geschaffen wird (TypeConverterAttribute stammt aus dem System). Daher kann der gewöhnliche Typkonverter-Ermittlungsmechanismus durch die Attributierung nicht unterstützt werden. Stattdessen verfügt der XAML-Parser über eine Liste von Typen, für die diese native Verarbeitung erforderlich ist, und verarbeitet diese Typen ähnlich wie echte primitive Typen. (Im Fall von DateTime umfasst dies einen Aufruf von Parse.)

Implementieren eines Typkonverters

TypeConverter

Im zuvor angegebenen Point-Beispiel wurde die Klasse PointConverter erwähnt. Bei .NET Framework-Implementierungen von XAML sind alle Typkonverter, die für XAML-Zwecke verwendet werden, Klassen, die von der Basisklasse TypeConverter abgeleitet werden. Die TypeConverter-Klasse gab es in .NET Framework-Versionen, die XAML vorausgehen. Eine der ursprünglichen Verwendungsweisen bestand in der Bereitstellung der Zeichenfolgenkonvertierung für Eigenschaftendialogfelder in visuellen Designern. Für XAML wurde die Rolle von TypeConverter erweitert. Er stellt jetzt auch die Basisklasse für die Konvertierung in und aus Zeichenfolgen dar, die die Analyse eines Zeichenfolgenattributwerts und möglicherweise das Verarbeiten eines Laufzeitwerts einer bestimmten Objekteigenschaft zurück in eine Zeichenfolge für die Serialisierung als Attribut ermöglicht.

TypeConverter definiert vier Member, die für die Konvertierungen in und aus Zeichenfolgen für XAML-Verarbeitungszwecke relevant sind:

Von diesen ist ConvertFrom die wichtigste Methode. Diese Methode konvertiert die Eingabezeichenfolge in den erforderlichen Objekttyp. Streng genommen könnte die ConvertFrom-Methode implementiert werden, um eine viel breitere Palette von Typen in den vom Konverter beabsichtigten Zieltyp zu konvertieren. Die Methode könnte somit für Zwecke verwendet werden, die über XAML hinausgehen, z. B. die Unterstützung von Konvertierungen zur Laufzeit. Für XAML-Zwecke ist es nur der Codepfad, der eine wichtige String-Eingabe verarbeiten kann.

Die nächste wichtigste Methode ist ConvertTo. Wenn eine Anwendung in eine Markupdarstellung umgewandelt wird (z. B. wenn sie in XAML als Datei gespeichert wird), ist ConvertTo verantwortlich für die Erstellung einer Markupdarstellung. In diesem Fall stellt der für XAML wichtige Codepfad den Zeitpunkt der Übergabe des destinationType-Elements String dar.

CanConvertTo und CanConvertFrom sind Unterstützungsmethoden, die verwendet werden, wenn ein Dienst die Funktionen der TypeConverter -Implementierung abfragt. Sie müssen diese Methoden implementieren, um true für typspezifische Klassen zurückzugeben, welche die entsprechenden Konvertierungsmethoden Ihres Konverters unterstützen. Für XAML-Zwecke bedeutet dies in der Regel den String -Typ.

Kulturinformations- und Typkonverter für XAML

Jede TypeConverter-Implementierung kann über eine eindeutige Interpretation davon verfügen, was eine gültige Zeichenfolge für eine Konvertierung ausmacht oder die Typbeschreibung ignorieren, die als Parameter übergeben wird. Im Hinblick auf die Kultur und das Konvertieren von XAML-Typen gibt es eine wichtige Überlegung. Die Verwendung von lokalisierbaren Zeichenfolgen als Attributwerte wird von XAML vollständig unterstützt. Die Verwendung lokalisierbarer Zeichenfolgen als Typkonvertereingabe mit bestimmten kulturellen Anforderungen wird nicht unterstützt, weil Typkonverter für XAML-Attributwerte ein zwangsläufig festes Sprachverarbeitungsverhalten umfassen, in dem die en-US-Kultur verwendet wird. Weitere Informationen zu den Gründen für diese Einschränkung finden Sie in der XAML-Sprachspezifikation ([MS-XAML].

Da die Kultur ein Problem darstellen kann, verwenden einige Kulturen ein Komma als Dezimaltrennzeichen für Zahlen. Dies steht mit dem Verhalten in Konflikt, das viele der WPF XAML-Typkonverter aufweisen und darin besteht, ein Komma als Trennzeichen zu verwenden (auf Grundlage geschichtlicher Präzedenzfälle wie die allgemeine X,Y-Form oder durch Trennzeichen getrennte Listen). Sogar die Übergabe einer Kultur im umgebenden XAML (das Festlegen von Language oder xml:lang auf die Kultur sl-SI, ein Beispiel für eine Kultur, die ein Komma für Dezimalstellen so verwendet) löst das Problem nicht.

Implementieren von ConvertFrom

Damit die TypeConverter -Methode für diesen Konverter als eine ConvertFrom -Implementierung verwendet werden kann, die XAML unterstützt, muss sie eine Zeichenfolge als den value -Parameter akzeptieren. Wenn die Zeichenfolge ein gültiges Format aufwies und durch die TypeConverter-Implementierung konvertiert werden kann, muss das zurückgegebene Objekt eine Umwandlung zum Typ unterstützen, der von der Eigenschaft erwartet wird. Andernfalls muss die ConvertFrom -Implementierung nullzurückgeben.

Jede TypeConverter-Implementierung kann eine eigene Interpretation dessen haben, was eine gültige Zeichenfolge für eine Konvertierung ausmacht, und kann auch die als Parameter übergebene Typbeschreibung oder entsprechend übergebenen kulturellen Kontexte verwenden oder ignorieren. Bei der WPF-XAML-Verarbeitung werden jedoch möglicherweise nicht in allen Fällen Werte an den Kontext der Typbeschreibung weitergegeben. Die auf xml:lang basierende Kultur wird möglicherweise auch nicht weitergegeben.

Hinweis

Verwenden Sie auf gar keinen Fall die geschweiften Klammern,vor allem { , als ein mögliches Element Ihres Zeichenfolgenformats. Diese Zeichen sind als ein Eintrag reserviert und dienen dem Beenden einer Markuperweiterungssequenz.

Implementieren von ConvertTo

ConvertTo wird möglicherweise für die Serialisierungsunterstützung verwendet. Die Serialisierungsunterstützung durch ConvertTo für Ihren benutzerdefinierten Typ und dessen Typkonverter ist nicht unbedingt erforderlich. Wenn Sie jedoch ein Steuerelement implementieren oder die Serialisierung als Bestandteil der Features oder zum Entwerfen Ihrer Klasse verwenden, sollten Sie ConvertToimplementieren.

Damit die Verwendung als TypeConverter-Implementierung erfolgen kann, die XAML unterstützt, muss die ConvertTo-Methode für diesen Konverter eine Instanz des Typs (oder eines Werts) akzeptieren, die als value-Parameter unterstützt wird. Wenn der Parameter destinationType vom Typ String ist, muss das zurückgegebene Objekt in der Lage sein, als String umgewandelt zu werden. Die zurückgegebene Zeichenfolge muss einen serialisierten Wert von valuedarstellen. Im Idealfall sollte das von Ihnen ausgewählte Serialisierungsformat in der Lage sein, den gleichen Wert zu generieren, als wenn die Zeichenfolge an die ConvertFrom-Implementierung desselben Konverters weitergegeben werden würde, und zwar ohne erhebliche Informationsverluste.

Wenn der Wert weder serialisiert werden kann noch der Konverter die Serialisierung unterstützt, muss die ConvertTo-Implementierung null zurückgeben und darf in diesem Fall eine Ausnahme auslösen. Wenn Sie jedoch Ausnahmen auslösen, sollten Sie die Unfähigkeit in Bezug auf die Verwendung dieser Konvertierung als Bestandteil Ihrer CanConvertTo-Implementierung melden, sodass die bewährte Vorgehensweise in Bezug auf die Überprüfung mit CanConvertTo zunächst darin besteht, dass die Vermeidung von Ausnahmen unterstützt wird.

Wenn der Parameter destinationType nicht vom Typ String ist, können Sie Ihre eigene Konverterverarbeitung auswählen. Für gewöhnlich nehmen Sie eine Zurücksetzung auf die grundlegende Implementierungsverarbeitung vor, wodurch im grundlegendsten ConvertTo-Element eine bestimmte Ausnahme ausgelöst wird.

Implementieren von CanConvertTo

Ihre Implementierung CanConvertTo sollte true für destinationType vom Typ Stringzurückgeben und andernfalls die grundlegende Implementierung ableiten.

Implementieren von CanConvertFrom

Ihre Implementierung CanConvertFrom sollte true für sourceType vom Typ Stringzurückgeben und andernfalls die grundlegende Implementierung ableiten.

Anwenden von TypeConverterAttribute

Damit Ihr benutzerdefinierter Typkonverter als der agierende Typkonverter für eine benutzerdefinierte Klasse durch einen XAML-Prozessor verwendet wird, müssen Sie TypeConverterAttribute auf Ihre Klassendefinition anwenden. Beim ConverterTypeName , den Sie über das Attribut angeben, muss es sich um den Typnamen Ihres benutzerdefinierten Typkonverters handeln. Wenn ein XAML-Prozessor nach Anwendung dieses Attributs Werte verarbeitet, bei denen der Eigenschaftstyp Ihren benutzerdefinierten Klassentyp verwendet, kann es Zeichenfolgen eingeben und Objektinstanzen zurückgeben.

Sie können auch einen Typkonverter auf Grundlage einzelner Eigenschaften bereitstellen. Anstelle ein TypeConverterAttribute-Element auf die Klassendefinition anzuwenden, wenden Sie es auf eine Eigenschaftsdefinition (die Hauptdefinition, nicht die darin enthaltenen get/set-Implementierungen) an. Der Eigenschaftstyp muss mit dem Typ übereinstimmen, der durch Ihren benutzerdefinierten Typkonverter verarbeitet wird. Wenn dieses Attribut angewendet ist, wenn ein XAML-Prozessor Werte dieser Eigenschaft verarbeitet, kann es Eingabezeichenfolgen verarbeiten und Objektinstanzen zurückgeben. Die Typkonvertertechnik auf Grundlage einzelner Eigenschaften ist insbesondere nützlich, wenn Sie einen Eigenschaftstyp aus Microsoft .NET Framework oder einer anderen Bibliothek verwenden möchten, wo Sie die Klassendefinition weder steuern noch dort ein TypeConverterAttribute-Element anwenden können.

Siehe auch