TypeConverters en XAML

In dit onderwerp wordt het doel van typeconversie van tekenreeks geïntroduceerd als een algemene XAML-taalfunctie. In .NET Framework dient de TypeConverter klasse een bepaald doel als onderdeel van de implementatie voor een beheerde aangepaste klasse die kan worden gebruikt als een eigenschapswaarde in het gebruik van XAML-kenmerken. Als u een aangepaste klasse schrijft en u wilt dat exemplaren van uw klasse bruikbaar zijn als ingestelde XAML-kenmerkwaarden, moet u mogelijk een TypeConverterAttribute op uw klasse toepassen, een aangepaste TypeConverter klasse schrijven of beide.

Concepten voor typeconversie

XAML- en tekenreekswaarden

Wanneer u een kenmerkwaarde instelt in een XAML-bestand, is het oorspronkelijke type van die waarde een tekenreeks in pure tekst. Zelfs andere primitieven, zoals Double, zijn in eerste instantie teksttekenreeksen voor een XAML-processor.

Een XAML-processor heeft twee stukjes informatie nodig om een kenmerkwaarde te kunnen verwerken. Het eerste stukje informatie is het waardetype van de eigenschap die wordt ingesteld. Elke tekenreeks die een kenmerkwaarde definieert en die wordt verwerkt in XAML, moet uiteindelijk worden geconverteerd of omgezet in een waarde van dat type. Als de waarde een primitieve is die wordt begrepen door de XAML-parser (zoals een numerieke waarde), wordt een directe conversie van de tekenreeks geprobeerd. Als de waarde een opsomming is, wordt de tekenreeks gebruikt om te controleren of een naam overeenkomt met een benoemde constante in die opsomming. Als de waarde noch een door de parser begrepen primitieve waarde, noch een enumeratie is, moet het type in kwestie een instantie van het type, of een waarde, kunnen geven, gebaseerd op een geconverteerde string. Dit wordt gedaan door een type converterklasse aan te geven. Het typeconversieprogramma is effectief een helperklasse voor het leveren van waarden van een andere klasse, zowel voor het XAML-scenario als voor code-aanroepen in .NET-code.

Bestaand typeconversiegedrag gebruiken in XAML

Afhankelijk van uw bekendheid met de onderliggende XAML-concepten, gebruikt u mogelijk al het gedrag van typeconversie in de basistoepassing XAML zonder dit te realiseren. WPF definieert bijvoorbeeld letterlijk honderden eigenschappen die een waarde van het type Pointaannemen. Een Point is een waarde die een coördinaat in een tweedimensionale coördinaatruimte beschrijft en die eigenlijk slechts twee belangrijke eigenschappen heeft: X en Y. Wanneer u een punt in XAML opgeeft, geeft u het op als een tekenreeks met een scheidingsteken (meestal een komma) tussen de en X de Y waarden die u opgeeft. Voorbeeld: <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"/>.

Zelfs dit eenvoudige type en het eenvoudige gebruik van Point in XAML betreffen een typeconverter. In dit geval is dat de klasse PointConverter.

Het typeconverter voor Point dat op klasseniveau is gedefinieerd, stroomlijnt het gebruik van opmaak voor alle eigenschappen die Point aannemen. Zonder een typeomzetter hier, heeft u de volgende, veel uitgebreidere markup nodig voor hetzelfde voorbeeld zoals eerder weergegeven.

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

Of u de tekenreeks voor typeconversie of een uitgebreidere equivalente syntaxis wilt gebruiken, is over het algemeen een coderingsstijlkeuze. Uw werkstroom voor XAML-hulpprogramma's kan ook van invloed zijn op de wijze waarop waarden worden ingesteld. Sommige XAML-hulpprogramma's verzenden meestal de meest uitgebreide vorm van de opmaak, omdat het eenvoudiger is om terug te gaan naar ontwerpweergaven of een eigen serialisatiemechanisme.

Bestaande typeconversieprogramma's kunnen over het algemeen worden gedetecteerd op WPF- en .NET Framework-typen door een klasse (of eigenschap) te controleren op de aanwezigheid van een toegepaste TypeConverterAttributeklasse. Met dit kenmerk wordt de klasse genoemd die het ondersteunende typeconversieprogramma is voor waarden van dat type, voor XAML-doeleinden en mogelijk andere doeleinden.

Conversieprogramma's en uitbreidingen voor markeringen typen

Markeringsextensies en typeconversieprogramma's vullen orthogonale rollen in termen van XAML-processorgedrag en de scenario's waarop ze worden toegepast. Hoewel context beschikbaar is voor het gebruik van markeringsuitbreidingen, wordt het gedrag van typeconversie van eigenschappen waarbij een markeringsextensie een waarde biedt, over het algemeen niet gecontroleerd in de implementaties van markeringsuitbreidingen. Met andere woorden, zelfs als een markeringsextensie een tekenreeks retourneert als ProvideValue uitvoer, wordt het gedrag van typeconversie op die tekenreeks, zoals toegepast op een specifiek eigenschaps- of eigenschapswaardetype, niet aangeroepen. Over het algemeen is het doel van een markeringsextensie een tekenreeks te verwerken en een object te retourneren zonder dat er een typeconversieprogramma betrokken is.

Een veelvoorkomende situatie waarbij een markeringsextensie nodig is in plaats van een typeconversieprogramma, is om een verwijzing te maken naar een object dat al bestaat. In het beste geval kan een staatloze typeconversieprogramma alleen een nieuw exemplaar genereren, wat mogelijk niet wenselijk is. Zie Markup Extensions en WPF XAML voor meer informatie over markeringsextensies.

Systeemeigen typeconverters

In de WPF- en .NET Framework-implementatie van de XAML-parser zijn er bepaalde typen die systeemeigen typeconversieverwerking hebben, maar geen typen zijn die conventioneel als primitieven kunnen worden beschouwd. Een voorbeeld van een dergelijk type is DateTime. De reden hiervoor is gebaseerd op de werking van de .NET Framework-architectuur: het type DateTime wordt gedefinieerd in mscorlib, de meest eenvoudige bibliotheek in .NET. DateTime mag niet voorzien worden van een kenmerk dat afkomstig is van een andere assembly die een afhankelijkheid introduceert (TypeConverterAttribute komt uit System), zodat het gebruikelijke mechanisme voor het ontdekken van typeconverters via attributen niet kan worden ondersteund. In plaats daarvan heeft de XAML-parser een lijst met typen die een dergelijke systeemeigen verwerking nodig hebben en deze op dezelfde manier verwerken als de ware primitieven worden verwerkt. (In het geval van DateTime dit is een aanroep naar Parse.)

Een typeconversieprogramma implementeren

Type Converter

In het Point eerder gegeven voorbeeld werd de klasse PointConverter genoemd. Voor .NET-implementaties van XAML zijn alle typeconversieprogramma's die worden gebruikt voor XAML-doeleinden klassen die zijn afgeleid van de basisklasse TypeConverter. De TypeConverter klasse bestond in versies van .NET Framework die voorafging aan het bestaan van XAML. Een van de oorspronkelijke gebruiksopties was het leveren van tekenreeksconversie voor eigenschappendialoogvensters in visuele ontwerpers. Voor XAML wordt de rol TypeConverter uitgebreid met de basisklasse voor to-string- en from-stringconversies die het parseren van een tekenreekskenmerkwaarde mogelijk maken en mogelijk een runtimewaarde van een bepaalde objecteigenschap weer verwerken in een tekenreeks voor serialisatie als kenmerk.

TypeConverter definieert vier leden die relevant zijn voor het converteren naar en van tekenreeksen voor XAML-verwerkingsdoeleinden:

Van deze, de belangrijkste methode is ConvertFrom. Met deze methode wordt de invoertekenreeks geconverteerd naar het vereiste objecttype. Strikt genomen kan de ConvertFrom methode worden geïmplementeerd om een veel breder scala aan typen te converteren naar het beoogde doeltype van het conversieprogramma, en dus dienen doelen die verder gaan dan XAML, zoals het ondersteunen van runtimeconversies, maar voor XAML-doeleinden is het alleen het codepad dat een String invoer kan verwerken die van belang is.

De volgende belangrijkste methode is ConvertTo. Als een toepassing wordt geconverteerd naar een markuprepresentatie (bijvoorbeeld als deze als bestand wordt opgeslagen in XAML), is ConvertTo verantwoordelijk voor het produceren van deze markuprepresentatie. In dit geval is het codepad dat van belang is voor XAML wanneer u een destinationType van String doorgeeft.

CanConvertTo en CanConvertFrom zijn ondersteuningsmethoden die worden gebruikt wanneer een service de mogelijkheden van de TypeConverter-implementatie opvraagt. U moet deze methoden implementeren om true te retourneren voor typespecifieke gevallen die de equivalente conversiemethoden van uw conversieprogramma ondersteunen. Voor XAML-doeleinden betekent dit over het algemeen het String type.

Cultuurinformatie en typeconversieprogramma's voor XAML

Elke TypeConverter implementatie kan een eigen interpretatie hebben van wat een geldige tekenreeks voor een conversie is en kan ook de typebeschrijving gebruiken of negeren die als parameters is doorgegeven. Er is een belangrijke overweging met betrekking tot cultuur en XAML-typeconversie. Het gebruik van lokaliseerbare tekenreeksen als kenmerkwaarden wordt volledig ondersteund door XAML. Maar het gebruik van die lokaliseerbare tekenreeks als type converterinvoer met specifieke cultuurvereisten wordt niet ondersteund, omdat typeconversieprogramma's voor XAML-kenmerkwaarden een noodzakelijkerwijs gedrag voor parseren met vaste taal omvatten, met behulp van en-US cultuur. Raadpleeg de XAML-taalspecificatie ([MS-XAML]) voor meer informatie over de ontwerpredenen voor deze beperking.

Als voorbeeld waarbij cultuur een probleem kan zijn, gebruiken sommige culturen een komma als scheidingsteken voor decimalen voor getallen. Dit komt in conflict met het gedrag dat veel van de WPF XAML-typeconverters hebben: het gebruik van een komma als scheidingsteken (gebaseerd op historische precedenten, zoals de gebruikelijke X,Y-vorm of door komma's gescheiden lijsten). Zelfs het doorgeven van een cultuur in de omringende XAML (instelling Language of xml:lang aan de sl-SI cultuur, een voorbeeld van een cultuur die op deze manier een komma voor decimaal gebruikt) lost het probleem niet op.

ConvertFrom implementeren

Om bruikbaar te zijn als een TypeConverter-implementatie die XAML ondersteunt, moet de methode ConvertFrom van die converter een tekenreeks als de parameter value accepteren. Als de tekenreeks een geldig formaat heeft en kan worden geconverteerd door de TypeConverter implementatie, moet het geretourneerde object een cast kunnen ondersteunen naar het type dat door de verwachte eigenschap wordt verwacht. Anders moet de ConvertFrom-implementatie nullretourneren.

Elke TypeConverter implementatie kan een eigen interpretatie hebben van wat een geldige tekenreeks voor een conversie is en kan ook de typebeschrijving of cultuurcontexten gebruiken of negeren die als parameters worden doorgegeven. De WPF XAML-verwerking geeft mogelijk niet in alle gevallen waarden door aan de context van de typebeschrijving en wellicht ook geen cultuur op basis van xml:lang.

Opmerking

Gebruik de accolades, met name {, niet als een mogelijk element van de tekenreeksindeling. Deze tekens zijn gereserveerd als de begin- en eindtekens voor een markeringsextensievolgorde.

ConvertTo implementeren

ConvertTo wordt mogelijk gebruikt voor serialisatieondersteuning. Serialisatieondersteuning via ConvertTo voor uw aangepaste type en de bijbehorende typeconverter is niet absoluut vereist. Als u echter een besturingselement implementeert of serialisatie gebruikt als onderdeel van de functies of het ontwerp van uw klasse, moet u ConvertToimplementeren.

Om bruikbaar te zijn als een TypeConverter implementatie die XAML ondersteunt, moet de ConvertTo methode voor die converter een exemplaar van het ondersteunde type (of een waarde) als de value parameter accepteren. Wanneer de destinationType-parameter het type String is, moet het geretourneerde object als String kunnen worden gecast. De geretourneerde tekenreeks moet een geserialiseerde waarde van valuevertegenwoordigen. In het ideale geval moet de serialisatie-indeling die u kiest, in staat zijn om dezelfde waarde te genereren als die tekenreeks is doorgegeven aan de ConvertFrom implementatie van hetzelfde conversieprogramma, zonder aanzienlijk verlies van informatie.

Als de waarde niet kan worden geserialiseerd of het conversieprogramma geen ondersteuning biedt voor serialisatie, moet de implementatie ConvertTonull retourneren, en mag er in dit geval een uitzondering worden gegooid. Maar als u uitzonderingen genereert, moet u aangeven dat deze conversie niet kan worden gebruikt als onderdeel van uw CanConvertTo implementatie, zodat de best practice om eerst te controleren met CanConvertTo om uitzonderingen te voorkomen wordt ondersteund.

Als destinationType de parameter niet van het type String is, kunt u uw eigen omzetterverwerking kiezen. Normaal gesproken keert u terug naar basisimplementatiebeheer, die in de meest basale ConvertTo een specifieke uitzondering veroorzaakt.

CanConvertTo implementeren

Uw CanConvertTo-implementatie moet true retourneren voor destinationType van het type Stringen anders verwijzen naar de basisimplementatie.

CanConvertFrom implementeren

Uw CanConvertFrom-implementatie moet true retourneren voor sourceType van het type Stringen anders verwijzen naar de basisimplementatie.

De TypeConverterAttribute toepassen

Als u wilt dat uw conversieprogramma voor aangepaste typen wordt gebruikt als werkende typeconversieprogramma voor een aangepaste klasse door een XAML-processor, moet u het TypeConverterAttribute toepassen op de definitie van uw klasse. De ConverterTypeName die u via het kenmerk opgeeft, moet de typenaam van het conversieprogramma voor aangepaste typen zijn. Wanneer dit kenmerk is toegepast, kan een XAML-processor waarden verwerken waarbij het eigenschapstype gebruikmaakt van uw aangepaste klassetype, tekenreeksen invoeren en objectexemplaren retourneren.

U kunt ook per eigenschap een typeconversieprogramma opgeven. In plaats van een TypeConverterAttribute toe te passen op de klassedefinitie, past u deze toe op een eigenschapsdefinitie (de hoofddefinitie, niet de get/set implementaties erin). Het type van de eigenschap moet overeenkomen met het type dat wordt verwerkt door het conversieprogramma voor aangepaste typen. Wanneer met dit kenmerk wordt toegepast, kan een XAML-processor waarden van die eigenschap verwerken, invoerreeksen verwerken en objectexemplaren retourneren. De methode voor conversie per eigenschap is met name handig als u een eigenschapstype van Microsoft .NET Framework of vanuit een andere bibliotheek wilt gebruiken waarin u de klassedefinitie niet kunt beheren en daar geen toepassing op kunt toepassen TypeConverterAttribute .

Zie ook