Názvové skopy XAML

Názvový rozsah XAML ukládá relace mezi názvy objektů definovanými XAML a jejich ekvivalenty instance. Tento koncept se podobá širšímu významu názvového oboru v jiných programovacích jazycích a technologiích.

Jak jsou definovány názvové rozsahy XAML

Názvy v názvech XAML umožňují uživatelskému kódu odkazovat na objekty, které byly původně deklarovány v jazyce XAML. Vnitřní výsledek analýzy XAML spočívá v tom, že modul runtime vytvoří sadu objektů, které uchovávají některé nebo všechny relace, které tyto objekty měly v deklaracích XAML. Tyto relace jsou zachovány jako specifické vlastnosti objektů vytvořených objektů nebo jsou vystaveny pomocným metodám v rozhraních API programovacího modelu.

Nejběžnější použití názvu v názvovém oboru XAML je jako přímý odkaz na instanci objektu, což umožňuje proces kompilace značek jako součást sestavení projektu, v kombinaci s vygenerovanou metodou InitializeComponent v šablonách parciální třídy.

Můžete také použít metodu utility FindName sami za běhu k vrácení odkazu na objekty, které byly definovány s názvem v kódu XAML.

Další informace o akcích sestavení a XAML

Technicky vzato se stane, že samotný XAML prochází kompilátorem značek současně, kdy se XAML a částečná třída, které definuje pro kód, kompilují společně. Každý prvek objektu s atributem Name nebo x:Name definovaným v kódu generuje interní pole s názvem, který odpovídá názvu XAML. Toto pole je zpočátku prázdné. Pak třída vygeneruje InitializeComponent metoda, která je volána až po načtení XAML. V logice InitializeComponent se pak každé interní pole naplní návratovou hodnotou FindName pro ekvivalentní řetězec názvu. Tuto infrastrukturu si můžete prohlédnout tak, že se podíváte na soubory ".g" (generované) vytvořené pro každou stránku XAML v podsložce /obj projektu aplikace prostředí Windows Runtime po kompilaci. Pole a metoda InitializeComponent můžete také zobrazit jako členy výsledných sestavení, pokud na ně provádíte reflexi nebo jinak prozkoumáte jejich obsah jazykového rozhraní.

Poznámka:

Konkrétně pro aplikace rozšíření komponent Visual C++ (C++/CX) se pro kořenový prvek souboru XAML nevytváří podkladové pole pro odkaz x:Name. Pokud potřebujete odkazovat na kořenový objekt ze zákulisního kódu C++/CX, použijte jiná rozhraní API nebo procházení stromovou strukturou. Můžete například volat FindName pro známý pojmenovaný podřízený element a potom zavolat Parent.

Vytváření objektů za běhu pomocí XamlReader.Load

XAML lze také použít jako řetězcový vstup pro XamlReader.Load metoda, která funguje podobně jako počáteční operace analýzy zdroje XAML. XamlReader.Load vytvoří nový odpojený strom objektů za běhu. Odpojený strom je pak možné připojit k určitému bodu ve stromu hlavního objektu. Vytvořený objektový strom musíte explicitně propojit tak, že ho přidáte do kolekce vlastností obsahu, jako je například Children, nebo nastavením některé jiné vlastnosti, která přebírá hodnotu objektu (například načtení nové ImageBrush pro hodnotu vlastnosti Fill ).

Důsledky použití oboru názvů XAML u XamlReader.Load

Předběžný názvový rozsah XAML definovaný novým stromem objektů vytvořeným XamlReader.Load vyhodnotí všechny definované názvy v zadaném XAML pro jedinečnost. Pokud názvy v zadaném kódu XAML nejsou v tomto okamžiku interně jedinečné, XamlReader.Load vyvolá výjimku. Odpojený strom objektů se nepokoušá sloučit svůj názvový rozsah XAML s hlavním názvovým rozsahem XAML aplikace, pokud nebo když je připojen k hlavnímu stromu objektu aplikace. Po propojení stromů má vaše aplikace jednotný strom objektů, ale tento strom má v něm oddělené názvové skopy XAML. K dělení dochází ve spojovacích bodech mezi objekty, kde nastavíte nějakou vlastnost na hodnotu vrácenou z volání XamlReader.Load.

Komplikace diskrétních a odpojených názvových oborů XAML spočívá v tom, že volání metody FindName a přímé odkazy na spravované objekty již nefungují s jednotným názvovým rozsahem XAML. Místo toho konkrétní objekt, na který je FindName volána, určuje obor, přičemž oborem je XAML namescope, ve kterém se volající objekt nachází. V případě přímého odkazu na spravovaný objekt je rozsah odvozený třídou, ve které existuje kód. Kód pro interakci s "stránkou" obsahu aplikace za běhu obvykle existuje v částečné třídě, která zálohuje kořenovou "stránku", a proto je názvový rozsah XAML kořenovým názvovým rozsahem XAML.

Pokud zavoláte FindName pro získání pojmenovaného objektu v kořenovém názvovém oboru XAML, metoda nenajde objekty z diskrétního názvového oboru XAML vytvořeného XamlReader.Load. Pokud naopak zavoláte FindName z objektu získaného z diskrétního názvového oboru XAML, metoda nenajde pojmenované objekty v kořenovém názvovém oboru XAML.

Tento problém s diskrétním názvovým rozsahem XAML má vliv pouze na hledání objektů podle názvu v názvech XAML při použití volání FindName .

Pokud chcete získat odkazy na objekty definované v jiném názvovém oboru XAML, můžete použít několik technik:

  • Projděte celý strom v samostatných krocích s vlastnostmi Parent a/nebo kolekcemi, o kterých je známo, že existují ve struktuře objektového stromu (například kolekci vrácenou Panel.Children).
  • Pokud voláte z diskrétního jmenného rozsahu XAML a chcete kořenový jmenný rozsah XAML, je vždy snadné získat odkaz na hlavní okno, které se aktuálně zobrazuje. Kořen vizuálu (kořenový element XAML, označovaný také jako zdroj obsahu) můžete získat z aktuálního okna aplikace v jednom řádku kódu pomocí volání Window.Current.Content. Pak můžete přetypovat na FrameworkElement a volat FindName z tohoto kontextu.
  • Pokud voláte z kořenového názvového oboru XAML a chcete objekt v diskrétním názvovém oboru XAML, je nejlepší provést plánování dopředu v kódu a zachovat odkaz na objekt vrácený XamlReader.Load a pak přidán do hlavního stromu objektů. Tento objekt je nyní platným objektem pro volání FindName v diskrétním oboru názvů XAML. Tento objekt můžete ponechat dostupný jako globální proměnnou nebo ho jinak předat pomocí parametrů metody.
  • Pokud se chcete zcela vyhnout problémům s názvy a názvovým prostorem XAML, můžete analyzovat vizuální strom. Rozhraní API VisualTreeHelper umožňuje procházet strom vizuálu z hlediska nadřazených objektů a podřízených kolekcí na základě pozice a indexu.

Obory jmen XAML v šablonách

Šablony v XAML poskytují možnost opakovaně používat a znovu použít obsah jednoduchým způsobem, ale šablony můžou obsahovat i prvky s názvy definovanými na úrovni šablony. Stejná šablona se může na stránce používat vícekrát. Z tohoto důvodu šablony definují vlastní názvové rozsahy XAML nezávisle na stránce obsahující styl nebo šablonu. Podívejte se na tento příklad:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  >
  <Page.Resources>
    <ControlTemplate x:Key="MyTemplate">
      ....
      <TextBlock x:Name="MyTextBlock" />
    </ControlTemplate>
  </Page.Resources>
  <StackPanel>
    <SomeControl Template="{StaticResource MyTemplate}" />
    <SomeControl Template="{StaticResource MyTemplate}" />
  </StackPanel>
</Page>

V této části se stejná šablona použije na dva různé ovládací prvky. Pokud by šablony neměly diskrétní názvové skopy XAML, název MyTextBlock použitý v šabloně by způsobil kolizi názvů. Každá instance šablony má svůj vlastní názvový prostor XAML, takže v tomto příkladu by názvový prostor XAML každé instance šablony obsahoval přesně jeden název. Kořenový názvový prostor XAML však neobsahuje název z obou šablon.

Vzhledem k samostatným oborům názvů XAML vyžaduje vyhledání pojmenovaných prvků v šabloně z oboru stránky, kde je šablona použita, jinou techniku. Místo volání FindName u některého objektu ve stromu objektů nejprve získáte objekt, který má použitou šablonu, a potom volání GetTemplateChild. Pokud jste autor ovládacího prvku a generujete konvenci, kde konkrétní pojmenovaný prvek v použité šabloně je cílem chování, které je definováno samotným ovládacím prvkem, můžete použít Metodu GetTemplateChild z kódu implementace ovládacího prvku. Metoda GetTemplateChild je chráněna , takže k ní má přístup pouze autor ovládacího prvku. Existují také konvence, které by autoři ovládacích prvků měli dodržovat, aby mohli pojmenovat části a části šablony a hlásit je jako hodnoty atributů použité u třídy ovládacího prvku. Tato technika umožňuje zjistit názvy důležitých částí pro řízení uživatelů, kteří by mohli chtít použít jinou šablonu, která by potřebovala nahradit pojmenované části, aby se zachovaly funkce řízení.