Übersicht über Typkonverter für XAML
Typkonverter stellen Logik für einen Objektwriter bereit, der eine XAML-Markupzeichenfolge in bestimmte Objekte in einem Objektdiagramm konvertiert. In .NET Framework-XAML-Diensten muss der Typkonverter eine von TypeConverter abgeleitete Klasse sein. Einige Konverter unterstützen auch den XAML-Speicherpfad und können verwendet werden, um ein Objekt in eine Zeichenfolgenform im Serialisierungsmarkup zu serialisieren. In diesem Thema wird beschrieben, wie und wann Typkonverter in XAML aufgerufen werden. Außerdem werden Implementierungsempfehlungen für die Methodenüberschreibungen von TypeConverter bereitgestellt.
Dieses Thema enthält folgende Abschnitte.
- Typkonvertierungsbegriffe
- Implementieren eines Typkonverters
- Übernehmen des TypeConverterAttribute
- Zugreifen auf Dienstanbieterkontext aus der Implementierung einer Markuperweiterung
- Typkonverter im XAML-Knotenstream
- Verwandte Abschnitte
Typkonvertierungsbegriffe
In den folgenden Abschnitten werden grundlegende Verwendungskonzepte von Zeichenfolgen in XAML erläutert, und es wird beschrieben, wie Objektwriter in .NET Framework-XAML-Diensten Zeichenfolgenwerte anhand von Typkonvertern verarbeiten.
XAML und Zeichenfolgenwerte
Wenn Sie einen Attributwert in einer XAML-Datei festlegen, ist der ursprüngliche Typ dieses Werts allgemein gesprochen eine Zeichenfolge und im XML-Kontext ein Zeichenfolgenattributwert. Auch andere Primitive, z. B. Double, sind anfänglich Zeichenfolgen für einen XAML-Prozessor.
In den meisten Fällen erfordert ein XAML-Prozessor zum Verarbeiten eines Attributwerts zwei Informationen. Die erste Information ist der Werttyp der Eigenschaft, die festgelegt wird. Jede Zeichenfolge, die einen Attributwert definiert und in XAML verarbeitet wird, muss schließlich in einen Wert dieses Typs umgewandelt oder aufgelöst werden. Wenn es sich bei dem Wert um einen primitiven Typ handelt, der vom XAML-Parser verstanden wird (z. B. ein numerischer Wert), wird eine direkte Konvertierung der Zeichenfolge versucht. Wenn der Wert für das Attribut auf eine Enumeration verweist, wird die angegebene Zeichenfolge auf eine Namensübereinstimmung mit einer benannten Konstante in dieser Enumeration überprüft. Wenn es sich bei dem Wert weder um eine Primitive, die vom Parser verstanden wird, noch um einen Konstantennamen einer Enumeration handelt, muss der anwendbare Typ in der Lage sein, einen Wert oder einen Verweis basierend auf einer konvertierten Zeichenfolge bereitzustellen.
Hinweis |
---|
XAML-Sprachdirektiven verwenden keine Typkonverter. |
Typkonverter und Markuperweiterungen
Die Verwendung von Markuperweiterungen muss durch einen XAML-Prozessor verarbeitet werden, bevor auf Eigenschaftentypen oder andere Aspekte geprüft wird. Wenn z. B. eine normalerweise als Attribut festgelegte Eigenschaft eine Typkonvertierung aufweist, in einem bestimmten Fall aber durch die Verwendung einer Markuperweiterung festgelegt wird, wird zuerst das Markuperweiterungsverhalten verarbeitet. Eine typische Situation, in der eine Markuperweiterung erforderlich ist, ist ein Verweis auf ein bereits vorhandenes Objekt. Für diesen Fall kann ein zustandsloser Typkonverter nur eine neue Instanz generieren, was möglicherweise nicht erwünscht ist. Weitere Informationen zu Markuperweiterungen finden Sie unter Übersicht über Markuperweiterungen für XAML.
Systemeigene Typkonverter
In den WPF- und .NET-XAML-Dienstimplementierungen sind bestimmte CLR-Typen mit systemeigener Typkonvertierungsbehandlung vorhanden. Diese CLR-Typen sind im konventionellen Sinne jedoch keine Primitiven. Ein Beispiel für einen solchen Typ ist DateTime. Ein Grund dafür ist die Funktionsweise der .NET Framework-Architektur: Der DateTime-Typ ist in "mscorlib" definiert, der grundlegendsten Bibliothek in .NET. DateTime darf keinem Attribut zugeordnet werden, das aus einer anderen Assembly stammt, die eine Abhängigkeit einführt (TypeConverterAttribute stammt aus "System"). Der übliche Erkennungsmechanismus des Typkonverters mittels Zuordnung kann daher nicht unterstützt werden. Stattdessen verfügt der XAML-Parser über eine Liste mit Typen, die diese systemeigene Verarbeitung erfordern, und verarbeitet diese auf ähnliche Weise, wie die echten Primitiven verarbeitet werden. (Im Fall von DateTime umfasst diese Verarbeitung einen Aufruf von Parse.
Implementieren eines Typkonverters
In den folgenden Abschnitten wird die API der TypeConverter-Klasse erläutert.
TypeConverter
Bei der Verwendung von .NET Framework-XAML-Diensten sind alle Typkonverter, die für XAML-Zwecke verwendet werden, von der TypeConverter-Basisklasse abgeleitete Klassen. Die TypeConverter-Klasse wurde in NET Framework-Versionen vor der Einführung von XAML verwendet: Zu den ursprünglichen TypeConverter-Szenarien gehörte die Bereitstellung der Zeichenfolgenkonvertierung für Eigenschafts-Editoren in visuellen Designern.
Für XAML wird die Rolle von TypeConverter erweitert. Für XAML-Zwecke ist TypeConverter die Basisklasse für die Unterstützung bestimmter to- und from-Zeichenfolgenkonvertierungen. Die From-Zeichenfolge ermöglicht das Analysieren eines Zeichenfolgenattributwerts von XAML. Die To-Zeichenfolge aktiviert möglicherweise die Verarbeitung eines Laufzeitwerts einer bestimmten Objekteigenschaft zu einem XAML-Attribut für die Serialisierung.
Das TypeConverter-Element definiert vier Member, die für die Konvertierung von To- und From-Zeichenfolgen für XAML-Verarbeitungszwecke relevant sind:
Von diesen Membern ist die wichtigste Methode ConvertFrom, mit der die Eingabezeichenfolge in den erforderlichen Objekttyp konvertiert wird. Die ConvertFrom-Methode kann implementiert werden, um einen größeren Bereich von Typen in den beabsichtigten Zieltyp des Konverters zu konvertieren. Daher kann es auch für Zwecke hilfreich sein, die über XAMLs hinausgehen, z. B. zum Unterstützen von Laufzeitkonvertierungen. Zur XAML-Verwendung ist nur der Codepfad wichtig, der eine String-Eingabe verarbeiten kann.
Die zweitwichtigste Methode ist ConvertTo. Wenn eine Anwendung in eine Markupdarstellung konvertiert wird (wenn sie z. B. als Datei in XAML gespeichert wird), wird ConvertTo im größeren Szenario eines XAML-TextWriters verwendet, um eine Markupdarstellung zu erzeugen. In diesem Fall ist der für XAML wichtige Codepfad die Übergabe eines destinationType von String durch den Aufrufer.
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 für typspezifische Fälle, die von den entsprechenden Konvertierungsmethoden Ihres Konverters unterstützt werden, true zurückzugeben. Für XAML-Zwecke ist das im Allgemeinen der String-Typ.
Kulturinformationen und Typkonverter für XAML
Von jeder TypeConverter-Implementierung kann individuell interpretiert werden, was ein gültige Zeichenfolge für eine Umwandlung ist, und die Typbeschreibung, die als Parameter übergeben wird, kann auch verwendet oder ignoriert werden. Folgendes muss bei der Kultur- und XAML-Typkonvertierung beachtet werden: Obwohl die Verwendung lokalisierbarer Zeichenfolgen als Attributwerte von XAML unterstützt wird, können diese lokalisierbaren Zeichenfolgen bei bestimmten Kulturanforderungen nicht als Typkonvertereingabe verwendet werden. Diese Einschränkung ist darauf zurückzuführen, dass Typkonverter für XAML-Attributwerte zwangsläufig ein festes XAML-Sprachverarbeitungsverhalten aufweisen, das die en-US-Kultur verwendet. Weitere Informationen über die entwicklungsspezifischen Gründe für diese Einschränkung finden Sie in der XAML-Sprachspezifikation ([MS-XAML]) oder Übersicht über WPF-Globalisierung und -Lokalisierung).
Ein Beispiel dafür, dass die Kultur ein Problem darstellen kann, ist, dass einige Kulturen statt einem Punkt ein Komma als Dezimaltrennzeichen für Zahlen im Zeichenfolgenformat verwenden. Diese Verwendung ist mit dem Verhalten vieler vorhandener Typkonverter unvereinbar, von denen ein Komma als Trennzeichen verwendet wird. Durch die Übergabe einer Kultur durch xml:lang im umgebenden XAML wird das Problem nicht gelöst.
Implementieren von ConvertFrom
Die ConvertFrom-Methode für diesen Konverter muss eine Zeichenfolge als value-Parameter akzeptieren, um als TypeConverter-Implementierung mit XAML-Unterstützung verwendet werden zu können. Wenn die Zeichenfolge in einem gültigen Format vorliegt und von der TypeConverter-Implementierung konvertiert werden kann, muss das zurückgegebene Objekt eine Umwandlung in den von der Eigenschaft erwarteten Typ unterstützen. Andernfalls muss die ConvertFrom-Implementierung null zurückgeben.
Jede TypeConverter-Implementierung kann ihre eigene Interpretation einer gültigen Zeichenfolge für eine Umwandlung haben und kann auch die Typbeschreibungs- oder Kulturkontexte, die als Parameter übergeben werden, verwenden oder ignorieren. Die WPF XAML-Verarbeitung übergibt jedoch unter Umständen nicht in allen Fällen Werte an den Typbeschreibungskontext und außerdem keine auf xml:lang basierende Kultur.
Hinweis |
---|
Verwenden Sie keine geschweiften Klammern ({}) als Element des Zeichenfolgenformats. Dies gilt insbesondere für die öffnende geschweifte Klammer ({).Diese Zeichen sind für den Beginn und das Ende einer Markuperweiterungssequenz reserviert. |
Wenn der Typkonverter Zugriff auf einen XAML-Dienst des Objektwriters des .NET Framework XAML-Diensts haben muss, kann eine Ausnahme ausgelöst werden, der für den Kontext vorgenommene GetService-Aufruf gibt diesen Dienst jedoch nicht zurück.
Implementieren von ConvertTo
ConvertTo wird möglicherweise für die Serialisierungsunterstützung verwendet. Die Serialisierungsunterstützung für Ihren benutzerdefinierten Typ und seinen Typkonverter durch die ConvertTo-Methode ist keine absolute Anforderung. Wenn Sie jedoch ein Steuerelement implementieren oder eine Serialisierung als Teil der Features oder der Gestaltung Ihrer Klasse verwenden, sollten Sie ConvertTo implementieren.
Um als TypeConverter-Implementierung verwendet werden zu können, die XAML unterstützt, muss die ConvertTo-Methode für diesen Konverter eine Instanz des Typs (oder einen Wert) akzeptieren, der als value-Parameter unterstützt wird. Wenn der destinationType-Parameter vom Typ String ist, muss das zurückgegebene Objekt in String umwandelbar sein. Die zurückgegebene Zeichenfolge muss einen serialisierten Wert von value darstellen. Das von Ihnen gewählte Serialisierungsformat sollte ohne bedeutenden Informationsverlust ermöglichen, den gleichen Wert zu generieren, der generiert wird, wenn diese Zeichenfolge an die ConvertFrom-Implementierung desselben Konverters übergeben wird.
Wenn der Wert nicht serialisiert werden kann oder der Konverter die Serialisierung nicht unterstützt, muss die ConvertTo-Implementierung null zurückgeben und kann in diesem Fall eine Ausnahme ausgeben. Wenn Sie jedoch Ausnahmen auslösen, sollten Sie melden, dass es nicht möglich ist, diese Konvertierung als Teil der CanConvertTo-Implementierung zu verwenden, sodass die Best Practice unterstützt wird, zuerst eine Überprüfung mit CanConvertTo durchzuführen, um Ausnahmen zu vermeiden.
Wenn der destinationType-Parameter nicht vom Typ String ist, können Sie eine eigene Konverterbehandlung auswählen. In der Regel stellen Sie die Basisimplementierungsbehandlung wieder her, die in der ConvertTo eine bestimmte Ausnahme auslöst.
Wenn der Typkonverter Zugriff auf einen XAML-Dienst des Objektwriters des .NET Framework XAML-Diensts haben muss, kann eine Ausnahme ausgelöst werden, der für den Kontext vorgenommene GetService-Aufruf gibt diesen Dienst jedoch nicht zurück.
Implementieren von CanConvertFrom
Ihre CanConvertFrom-Implementierung sollte true für sourceType vom Typ String zurückgeben und andernfalls auf die Basisimplementierung zurückgreifen. Lösen Sie keine Ausnahmen über CanConvertFrom aus.
Implementieren von CanConvertTo
Ihre CanConvertTo-Implementierung sollte true für destinationType vom Typ String zurückgeben und andernfalls auf die Basisimplementierung zurückgreifen. Lösen Sie keine Ausnahmen über CanConvertTo aus.
Übernehmen des TypeConverterAttribute
Damit der benutzerdefinierte Typkonverter als aktiver Typkonverter für eine benutzerdefinierte Klasse der .NET Framework-XAML-Dienste verwendet werden kann, müssen Sie das .NET Framework attribute TypeConverterAttribute auf Ihre Klassendefinition anwenden. Der ConverterTypeName, den Sie über das Attribut angeben, muss der Typname des benutzerdefinierten Typkonverters sein. Wenn Sie dieses Attribut anwenden, können Zeichenfolgen eingegeben und Objektinstanzen zurückgegeben werden, wenn ein XAML-Prozessor Werte verarbeitet, sofern der Eigenschaftstyp Ihren benutzerdefinierten Klassentyp verwendet.
Sie können auch einen Typkonverter auf Eigenschaftenbasis bereitstellen. Anstatt ein .NET Framework attribute TypeConverterAttribute auf die Klassendefinition anzuwenden, sollten Sie es auf eine Eigenschaftendefinition anwenden (die Hauptdefinition, nicht die darin enthaltenen get/set-Implementierungen). Der Typ der Eigenschaft muss dem Typ entsprechen, der von Ihrem benutzerdefinierten Typkonverter verarbeitet wird. Bei Anwendung dieses Attributs können Zeichenfolgen verarbeitet und Objektinstanzen zurückgegeben werden, wenn ein XAML-Prozessor Werte dieser Eigenschaft verarbeitet. Die Typkonvertertechnik auf Eigenschaftenbasis ist vor allem dann hilfreich, wenn Sie einen Eigenschaftentyp von Microsoft .NET Framework oder einer anderen Bibliothek verwenden, bei dem Sie die Klassendefinition nicht steuern können und kein TypeConverterAttribute anwenden können.
Um ein Typkonvertierungsverhalten für einen benutzerdefinierten zugeordneten Member bereitzustellen, wenden Sie TypeConverterAttribute auf die Get-Accessormethode des Implementierungsmusters für den zugeordneten Member an.
Zugreifen auf Dienstanbieterkontext aus der Implementierung einer Markuperweiterung
Die verfügbaren Dienste sind für jeden Wertkonverter gleich. Der Unterschied besteht darin, wie die einzelnen Wertkonverter den Dienstkontext empfangen. Der Zugriff auf Dienste und die verfügbaren Dienste sind im Thema Typkonverter und Markuperweiterungen für XAML dokumentiert.
Typkonverter im XAML-Knotenstream
Beim Arbeiten mit einem XAML-Knotenstream, wird das Aktions- oder Endergebnis eines Typkonverters noch nicht ausgeführt. In einem Ladepfad ist dies die Attributzeichenfolge, die schließlich typkonvertiert werden muss, um verbleibende Zeichen als Textwert innerhalb eines Start- und End-Members zu laden. Der Typkonverter, der schließlich für diesen Vorgang benötigt wird, kann mit der XamlMember.TypeConverter-Eigenschaft bestimmt werden. Ob ein gültiger Wert von XamlMember.TypeConverter abgerufen werden kann, ist jedoch davon abhängig, ob ein XAML-Schemakontext verfügbar ist, der auf solche Informationen über den zugrunde liegenden Member oder den Typ des Objektwerts zugreifen kann, den der Member verwendet. Das Aufrufen des Typkonvertierungsverhaltens erfordert ebenfalls den XAML-Schemakontext, da dafür eine Typzuordnung und das Erstellen einer Konverterinstanz erforderlich sind.