Sdílet prostřednictvím


Rozšíření značek a WPF XAML

Toto téma představuje koncept značkovacích rozšíření pro XAML, včetně jejich pravidel syntaxe, účelu a objektového modelu třídy, který tvoří jejich základ. Rozšíření značek jsou obecnou funkcí jazyka XAML a implementace služeb XAML .NET. Toto téma podrobně popisuje rozšíření značkování pro použití ve WPF XAML.

Procesory XAML a rozšíření značek

Obecně řečeno, analyzátor XAML může interpretovat hodnotu atributu jako literálový řetězec, který lze převést na primitivní, nebo ho nějakým způsobem převést na objekt. Jedním z takových prostředků je odkazování na převaděč typů; toto je dokumentováno v tématu TypeConverters a XAML. Existují však scénáře, ve kterých se vyžaduje jiné chování. Například procesor XAML lze instruovat, že hodnota atributu by neměla vést k novému objektu v grafu objektu. Místo toho by měl atribut vést k grafu objektů, který vytváří odkaz na již vytvořený objekt v jiné části grafu nebo na statický objekt. Dalším scénářem je, že procesor XAML může být instruován k použití syntaxe, která poskytuje konstruktoru objektu jiné než výchozí argumenty. Jedná se o typy scénářů, ve kterých může značkovací rozšíření poskytnout řešení.

Základní syntaxe rozšíření značek

Rozšíření značkování lze implementovat tak, aby poskytovalo hodnoty pro vlastnosti při použití atributu, vlastnosti při použití elementu vlastnosti, nebo obojí.

Pokud se používá k zadání hodnoty atributu, syntaxe, která identifikuje sekvenci značkovacího rozšíření pro XAML zpracovatele, je přítomnost otevíracích a uzavíracích složených závorek ({ a }). Typ rozšíření značek se pak identifikuje pomocí řetězcového tokenu, který bezprostředně následuje po levé složené závorce.

Když se používá v syntaxi elementu vlastnosti, rozšíření značky je vizuálně stejné jako jakýkoli jiný prvek použitý k poskytnutí hodnoty elementu vlastnosti: deklarace elementu XAML, která odkazuje na třídu rozšíření značky jako prvek, uzavřený do úhlových závorek (<>).

Rozšíření značek XAML-Defined

Existuje několik rozšíření označení, které nejsou specifické pro implementaci XAML ve WPF, ale jsou spíše implementace vnitřních objektů nebo funkcí XAML jako jazyka. Tato rozšíření značek jsou implementována v sestavení System.Xaml jako součást obecných služeb XAML rozhraní .NET Framework a jsou v jménovém prostoru jazyka XAML. Pokud jde o běžné použití značkování, tato značkovací rozšíření jsou obvykle identifikovatelná předponou x:. Základní třída MarkupExtension (také definovaná v System.Xaml) poskytuje šablonu, kterou by měla používat všechna rozšíření značek, aby byla podporována v XAML čtečkách a zapisovačích, včetně WPF XAML.

  • x:Type poskytuje objekt Type pro pojmenovaný typ. Toto zařízení se nejčastěji používá ve stylech a šablonách. Podrobnosti najdete v x:Type Rozšíření značek.

  • x:Static vytváří statické hodnoty. Hodnoty pocházejí z entit kódu typu hodnota, které nejsou přímo typem hodnoty cílové vlastnosti, ale lze je vyhodnotit na tento typ. Podrobnosti najdete v rozšíření Markup Extension x:Static .

  • x:Null určuje null jako hodnotu vlastnosti a lze ji použít buď pro atributy, nebo hodnoty elementu vlastnosti. Podrobnosti najdete v x:Null Markup Extension.

  • x:Array poskytuje podporu pro vytváření univerzálních polí v syntaxi XAML v případech, kde se záměrně nevyužívá podpora kolekcí poskytovaná základními prvky WPF a řídicími modely. Podrobnosti naleznete v tématu x:Array Markup Extension.

Poznámka

Předpona x: se používá pro typické mapování oboru názvů základních funkcí jazyka XAML v kořenovém prvku souboru XAML nebo ve výrobním prostředí. Například šablony sady Visual Studio pro aplikace WPF iniciují soubor XAML pomocí tohoto mapování x:. Ve vlastním mapování oboru názvů XAML můžete zvolit jiný token předpony, ale tato dokumentace předpokládá výchozí mapování x: jako prostředek identifikace entit, které jsou definovanou součástí oboru názvů XAML pro jazyk XAML, a ne výchozí obor názvů WPF nebo jiné obory názvů XAML nesouvisejí s konkrétní architekturou.

WPF-Specific Rozšíření značek

Nejběžnější rozšíření značek používaná v programování WPF jsou ty, které podporují odkazy na prostředky (StaticResource a DynamicResource), a ty, které podporují datovou vazbu (Binding).

  • StaticResource poskytuje hodnotu vlastnosti nahrazením hodnoty již definovaného prostředku. Vyhodnocení StaticResource se nakonec provádí v době načítání XAML a nemá přístup k grafu objektů za běhu. Podrobnosti najdete v tématu rozšíření značek StaticResource.

  • DynamicResource poskytuje hodnotu vlastnosti tím, že ji za běhu použije jako referenci na prostředek. Dynamický odkaz na prostředek vynucuje nové vyhledávání pokaždé, když je daný prostředek přístupný, a má přístup ke grafu objektů za běhu. Pro získání tohoto přístupu je koncept DynamicResource podporován vlastnostmi závislostí v systému vlastností WPF a vyhodnocenými výrazy. Proto můžete použít pouze DynamicResource pro cíl vlastnosti závislosti. Podrobnosti viz Rozšíření značek DynamicResource.

  • Binding poskytuje datovou vázanou hodnotu pro vlastnost pomocí kontextu dat uplatněného na rodičovský objekt za běhu. Toto rozšíření značkovacího jazyka je poměrně složité, protože umožňuje významnou vloženou syntaxi pro zadání datové vazby. Podrobnosti najdete v tématu rozšíření značek vazby.

  • RelativeSource poskytuje zdrojové informace pro Binding, které mohou orientovat se v několika možných relacích v objektovém stromu za běhu. Poskytuje specializovaný zdroj vazeb vytvořených v šablonách s více použitími nebo vytvořených v kódu bez úplného vědomí okolního stromu objektů. Podrobnosti viz RelativeSource MarkupExtension.

  • TemplateBinding umožňuje šabloně ovládacího prvku používat hodnoty pro vlastnosti šablony, které pocházejí z vlastností definovaných objektem modelu třídy, která bude šablonu používat. Jinými slovy, vlastnost v definici šablony má přístup k kontextu, který existuje pouze po použití šablony. Podrobnosti najdete v tématu Rozšíření značek TemplateBinding. Další informace o praktickém použití TemplateBindingnaleznete v ukázce Styling s ControlTemplates.

  • ColorConvertedBitmap podporuje relativně pokročilý scénář vytváření obrázků. Podrobnosti viz ColorConvertedBitmap Markup Extension.

  • ComponentResourceKey a ThemeDictionary podporují aspekty vyhledávání prostředků, zejména pro prostředky a motivy zabalené s vlastními ovládacími prvky. Další informace naleznete v tématu ComponentResourceKey Markup Extension, ThemeDictionary Markup Extensionnebo Control Authoring Overview.

*Rozšiřující třídy

Jak pro obecný jazyk XAML, tak pro rozšíření značek specifických pro WPF je chování každého rozšíření značek procesoru XAML identifikováno prostřednictvím třídy *Extension, která odvozuje z MarkupExtensiona poskytuje implementaci metody ProvideValue. Tato metoda u každého rozšíření poskytuje objekt, který je vrácen při vyhodnocení rozšíření značkovacího jazyka. Vrácený objekt se obvykle hodnotí na základě různých textových tokenů, které jsou předány markup rozšíření.

Například třída StaticResourceExtension poskytuje základní implementaci pro skutečné vyhledávání prostředků, aby její implementace ProvideValue vrátila objekt, který je požadován, přičemž vstupem této konkrétní implementace je řetězec používaný k vyhledání prostředku pomocí jeho x:Key. Většina těchto podrobností o implementaci není důležitá, pokud používáte existující značkovací rozšíření.

Některá rozšíření značek nepoužívají řetězcové tokenové argumenty. Je to buď proto, že vrací statickou nebo konzistentní hodnotu, nebo protože kontext pro hodnotu, která by se měla vrátit, je k dispozici prostřednictvím jedné ze služeb předávaných prostřednictvím parametru serviceProvider.

Vzor pojmenování *Extension je pro usnadnění a konzistenci. Není nutné, aby procesor XAML identifikoval tuto třídu jako podporu značkovacího rozšíření. Pokud vaše kódová základna zahrnuje System.Xaml a používá implementace XAML Services .NET Frameworku, stačí odvodit z MarkupExtension a podporovat syntaxi konstrukce, abyste byli rozpoznáni jako rozšíření značkovacího jazyka XAML. WPF definuje třídy podporující rozšíření značek, které nedodržují *Extension vzor pojmenování, například Binding. Důvodem bývá to, že třída podporuje scénáře, které přesahují běžné rozšíření jazyka pro označování. V případě Bindingtato třída podporuje přístup za běhu k metodám a vlastnostem objektu pro scénáře, které nemají nic společného s XAML.

Interpretace inicializačního textu třídy rozšíření

Řetězcové tokeny, které následují za názvem rozšíření značek a které jsou stále v rámci složených závorek, jsou interpretovány procesorem XAML jedním z následujících způsobů:

  • Čárka vždy představuje oddělovač nebo delimitér jednotlivých tokenů.

  • Pokud jednotlivé oddělené tokeny neobsahují žádné znaménka rovná se, považuje se každý token za argument konstruktoru. Každý parametr konstruktoru musí být uveden jako typ očekávaný tímto podpisem a ve správném pořadí očekávaném tímto podpisem.

    Poznámka

    Aby procesor XAML mohl správně fungovat, musí zavolat konstruktor, který odpovídá počtu párů. Z tohoto důvodu, pokud implementujete rozšíření vlastních značek, nezadávejte více konstruktorů se stejným počtem argumentů. Chování procesoru XAML není definováno pro situaci, když existuje více než jedna cesta konstruktoru rozšíření značek se stejným počtem parametrů. Měli byste však předpokládat, že procesor XAML může vyvolat výjimku při použití, pokud tato situace existuje v definicích typů rozšíření značek.

  • Pokud jednotlivé oddělené tokeny obsahují znaménka rovná se, pak procesor XAML nejprve volá konstruktor bez parametrů pro rozšíření značkování. Potom se každý pár name=value interpretuje jako název vlastnosti, který existuje v rozšíření značek, a hodnotu, která se má k této vlastnosti přiřadit.

  • Pokud existuje paralelní výsledek mezi chováním konstruktoru a nastavováním vlastností v rozšíření značek, nezáleží na tom, jaké chování použijete. Je běžnější použít páry vlastnost =hodnota pro rozšíření značek, které mají více než jednu nastavitelnou vlastnost, pokud jen proto, že to činí vaše značení úmyslnější a je méně pravděpodobné, že omylem zaměníte parametry konstruktoru. (Pokud zadáte dvojice property=value, mohou tyto vlastnosti být v libovolném pořadí.) Navíc neexistuje žádná záruka, že rozšíření značek poskytne parametr konstruktoru, který nastaví všechny jeho nastavitelné vlastnosti. Například Binding je markup extension s mnoha vlastnostmi, které lze nastavit pomocí rozšíření ve formátu vlastnost=hodnotu, ale Binding podporuje pouze dva konstruktory: konstruktor bez parametrů a jeden, který nastavuje počáteční cestu.

  • Do rozšíření značek nelze předat literální čárku bez použití značky úniku.

Escape sekvence a rozšíření značek

Zpracování atributů v procesoru XAML používá složené závorky jako indikátory sekvence značkovacích rozšíření. Je také možné v případě potřeby vytvořit hodnotu atributu literálu složené závorky zadáním únikové sekvence pomocí prázdné dvojice složených závorek následované literálovou složenou závorkou. Viz {} úniková sekvence – rozšíření značek.

Vnoření rozšíření značek v použití XAML

Podporuje se vnoření více značkových rozšíření a každé z nich bude vyhodnoceno od nejhlubšího po nejpovrchnější. Představte si například následující využití:

<Setter Property="Background"  
  Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />  

V tomto použití se příkaz x:Static vyhodnotí jako první a vrátí řetězec. Tento řetězec se pak použije jako argument pro DynamicResource.

Syntax rozšíření značek a syntaxe vlastnostních elementů

Používá-li se jako element objektu, který vyplňuje hodnotu prvku vlastnosti, je třída rozšíření značek vizuálně nerozlišitelná od běžného objektu, který lze použít v XAML. Praktický rozdíl mezi typickým prvkem objektu a rozšířením značek spočívá v tom, že rozšíření značek je buď vyhodnoceno na typovou hodnotu, nebo odloženo jako výraz. Proto se mechanismy pro případné chyby typů hodnot vlastností pro rozšíření značek budou lišit, podobně jako se zachází s vlastnostmi s pozdní vazbou v jiných programovacích modelech. Běžný prvek objektu bude vyhodnocen pro shodu typu s cílovou vlastností, která je nastavena při analýze XAML.

Většina rozšíření značek, pokud se používá v syntaxi prvku objektu k vyplnění prvku vlastnosti, nebude mít obsah ani žádnou další syntaxi vlastností uvnitř. Proto byste uzavřeli značku elementu objektu a neposkytli žádné podřízené prvky. Pokaždé, když procesor XAML nalezne jakýkoli prvek objektu, je volán konstruktor pro tuto třídu, který instanciuje objekt vytvořený z parcovaného prvku. Třída rozšíření značek se nijak neliší: pokud chcete, aby bylo rozšíření značek použitelné v syntaxi elementu objektu, je nutné zadat konstruktor bez parametrů. Některá existující značkovací rozšíření mají alespoň jednu požadovanou hodnotu vlastnosti, kterou je nutné zadat pro efektivní inicializaci. Pokud ano, tato hodnota vlastnosti je obvykle uvedena jako atribut vlastnosti u elementu object. Na referenčních stránkách jazykových funkcí oboru názvů XAML (x:) a rozšíření WPF XAML budou zaznamenány rozšíření značek, které mají požadované vlastnosti (a názvy požadovaných vlastností). Referenční stránky také uvedou, pokud je syntaxe objektového prvku nebo syntaxe atributu zakázána pro určité rozšíření značkování. Je rozšíření značek x:Array, což nemůže podporovat syntaxi atributů, protože obsah tohoto pole musí být zadán v rámci označování jako obsah. Obsah pole se zpracovává jako obecné objekty, proto není možné použít žádný výchozí převaděč typů pro atribut. Rozšíření značek x:Array vyžaduje také parametr type.

Viz také