Obory názvů WPF XAML

Názvové rozsahy XAML jsou koncept, který identifikuje objekty definované v jazyce XAML. Názvy v názvovém oboru XAML lze použít k navázání relací mezi názvy objektů definovanými XAML a jejich ekvivalenty instance ve stromu objektů. Názvy XAML ve spravovaném kódu WPF se obvykle vytvářejí při načítání jednotlivých kořenových stránek XAML pro aplikaci XAML. Názvové rozsahy XAML jako programovací objekt jsou definovány INameScope rozhraním a jsou také implementovány praktickou třídou NameScope.

Názvové rozsahy v načtených aplikacích XAML

V širším kontextu programování nebo počítačové vědy často zahrnují koncepty programování princip jedinečného identifikátoru nebo názvu, který lze použít pro přístup k objektu. Pro systémy, které používají identifikátory nebo názvy, názvový obor definuje hranice, ve kterých bude proces nebo technika prohledávat, pokud je požadován objekt tohoto názvu, nebo hranice, ve kterých se vynucuje jedinečnost identifikace názvů. Tyto obecné principy platí pro názvové rozsahy XAML. Ve WPF jsou názvové skopy XAML vytvořeny v kořenovém elementu pro stránku XAML při načtení stránky. Každý název zadaný na stránce XAML počínaje kořenem stránky se přidá do příslušného oboru názvů XAML.

V jazyce WPF XAML řídí elementy, které jsou běžnými kořenovými elementy (například Pagea Window) vždy řídí názvový rozsah XAML. Pokud prvek, například FrameworkElement nebo FrameworkContentElement je kořenovým prvkem stránky v kódu, přidá procesor Page XAML kořen implicitně, aby Page mohl poskytnout funkční názvový rozsah XAML.

Poznámka:

Akce sestavení WPF vytvoří názvový rozsah XAML pro produkční prostředí XAML, i když nejsou Name definovány žádné prvky x:Name v kódu XAML.

Pokud se pokusíte použít stejný název dvakrát v libovolném názvovém oboru XAML, vyvolá se výjimka. Pro WPF XAML, který má kód za sebou a je součástí kompilované aplikace, je výjimka vyvolána při sestavení akce sestavení WPF při vytváření vygenerované třídy pro stránku během počáteční kompilace značek. U XAML, který není kompilován žádnou akcí sestavení, mohou být při načtení XAML vyvolány výjimky související s problémy s názvovým rozsahem XAML. Návrháři XAML mohou také očekávat problémy s názvem XAML v době návrhu.

Přidání objektů do stromů objektů modulu runtime

Okamžik, kdy se xaml analyzuje, představuje okamžik v čase, kdy se vytvoří a definuje názvovýscope WPF XAML. Pokud přidáte objekt do stromu objektů v určitém okamžiku po kódu XAML, který vytvořil tento strom byl analyzován, Name nebo x:Name hodnota nového objektu automaticky neaktualizuje informace v názvovém oboru XAML. Chcete-li přidat název objektu do WPF XAML namescope po načtení XAML, je nutné volat odpovídající implementaci RegisterName objektu, který definuje názvovýscope XAML, což je obvykle kořen stránky XAML. Pokud název není zaregistrovaný, přidaný objekt nemůže být odkazován pomocí metod, jako FindNameje , a tento název nelze použít pro cílení na animace.

Nejběžnějším scénářem pro vývojáře aplikací je, že použijete RegisterName k registraci názvů do oboru názvů XAML v aktuálním kořenovém adresáři stránky. RegisterName je součástí důležitého scénáře pro scénáře, které cílí na objekty pro animace. Další informace najdete v tématu Přehled scénářů.

Pokud voláte RegisterName objekt jiný než objekt, který definuje názvový rozsah XAML, je název stále registrován do oboru názvů XAML, který je v volajícím objektu, jako byste volali RegisterName na objekt xaml namescope definující objekt.

Názvové skopy XAML v kódu

V kódu můžete vytvořit a pak použít názvové názvové skopy XAML. Rozhraní API a koncepty zahrnuté do vytváření názvového oboru XAML jsou stejné i pro použití čistého kódu, protože procesor XAML pro WPF používá tato rozhraní API a koncepty při zpracování samotného XAML. Koncepty a rozhraní API existují hlavně pro účely schopnosti najít objekty podle názvu v rámci stromu objektů, který je obvykle definován částečně nebo zcela v XAML.

Pro aplikace vytvořené programově a ne z načteného XAML musí objekt, který definuje názvovýscope XAML implementovat INameScope, nebo být nebo FrameworkContentElement odvozenou FrameworkElement třídou, aby bylo možné podporovat vytvoření názvového oboru XAML ve svých instancích.

Pro každý prvek, který není načten a zpracován procesorem XAML, xaml namescope pro objekt není vytvořen nebo inicializován ve výchozím nastavení. Musíte explicitně vytvořit nový názvový rozsah XAML pro jakýkoli objekt, do kterého chcete následně zaregistrovat názvy. Pokud chcete vytvořit názvový rozsah XAML, zavoláte statickou SetNameScope metodu. Zadejte objekt, který ho bude vlastnit jako dependencyObject parametr, a nový NameScope konstruktor volání jako value parametr.

Pokud objekt zadaný jako dependencyObjectSetNameScope pro není INameScope implementace nebo FrameworkElementFrameworkContentElement, volání RegisterName na všechny podřízené prvky nebude mít žádný vliv. Pokud se vám nepodaří explicitně vytvořit nový názvový rozsah XAML, volání RegisterName vyvolá výjimku.

Příklad použití rozhraní XAML namescope API v kódu najdete v tématu Definování oboru názvů.

Názvové rozsahy XAML ve stylech a šablonách

Styly a šablony ve WPF poskytují možnost opakovaně používat a znovu používat obsah jednoduchým způsobem. Styly a šablony ale můžou obsahovat i prvky s názvy XAML definovanými na úrovni šablony. Stejná šablona se může na stránce používat vícekrát. Z tohoto důvodu styly a šablony definují vlastní názvové rozsahy XAML nezávisle na libovolném umístění ve stromu objektů, ve kterém je použit styl nebo šablona.

Představte si následující 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="MyButtonTemplate" TargetType="{x:Type Button}">
      <Border BorderBrush="Red" Name="TheBorder" BorderThickness="2">
        <ContentPresenter/>
      </Border>      
    </ControlTemplate>
  </Page.Resources>
  <StackPanel>
    <Button Template="{StaticResource MyButtonTemplate}">My first button</Button>
    <Button Template="{StaticResource MyButtonTemplate}">My second button</Button>
  </StackPanel>
</Page>

V této části se stejná šablona použije na dvě různá tlačítka. Pokud šablony nemají diskrétní názvové názvové skopy XAML, TheBorder způsobí název použitý v šabloně kolize názvů XAML. Každá instance šablony má svůj vlastní názvový rozsah XAML, takže v tomto příkladu by v každém názvovém oboru názvů XAML každé instance šablony obsahoval přesně jeden název.

Styly také definují vlastní názvový rozsah XAML, většinou tak, aby části scénářů mohly mít přiřazené konkrétní názvy. Tyto názvy umožňují řídit specifické chování, které bude cílit na prvky tohoto názvu, i když byla šablona znovu definována jako součást přizpůsobení ovládacího prvku.

Vzhledem k samostatným oborům názvů XAML je nalezení pojmenovaných prvků v šabloně náročnější než nalezení neschybovaného pojmenovaného prvku na stránce. Nejdřív je potřeba určit použitou šablonu získáním Template hodnoty vlastnosti ovládacího prvku, ve kterém je šablona použita. Potom zavoláte verzi FindNamešablony a předáte ovládací prvek, ve kterém byla šablona použita jako druhý parametr.

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ěná, takže k ní má přístup pouze autor ovládacího prvku.

Pokud pracujete v rámci šablony a potřebujete se dostat do oboru názvů XAML, ve kterém je šablona použita, získejte hodnotu TemplatedParenta zavolejte FindName tam. Příkladem práce v rámci šablony by bylo, kdybyste psali implementaci obslužné rutiny události, kde bude událost vyvolána z elementu v použité šabloně.

FrameworkElementFindNamea RegisterNameUnregisterName metody. Pokud objekt, který tyto metody voláte, vlastní názvový rozsah XAML, metody volají metody do metod příslušného názvového oboru XAML. V opačném případě se nadřazený prvek zkontroluje, jestli vlastní názvový rozsah XAML, a tento proces pokračuje rekurzivně, dokud se nenajde názvový rozsah XAML (kvůli chování procesoru XAML je zaručeno, že v kořenovém adresáři je názvový rozsah XAML). FrameworkContentElement má podobné chování, s výjimkou, že nikdy nebude FrameworkContentElement vlastnit xaml namescope. Metody existují tak FrameworkContentElement , aby volání bylo možné přesměrovat nakonec do nadřazeného elementu FrameworkElement .

SetNameScope slouží k mapování nového názvového oboru XAML na existující objekt. Pokud chcete resetovat nebo vymazat názvový rozsah XAML, můžete volat SetNameScope více než jednou, ale to není běžné použití. GetNameScope Také se obvykle nepoužívá z kódu.

Implementace XAML Namescope

Následující třídy implementují INameScope přímo:

ResourceDictionary nepoužívá názvy XAML ani názvové názvové názvy ; místo toho používá klíče, protože se jedná o implementaci slovníku. Jediným důvodem, proč ResourceDictionary implementuje INameScope , je, aby mohl vyvolat výjimky uživatelského kódu, které pomáhají objasnit rozdíl mezi skutečným názvovým rozsahem XAML a způsobem ResourceDictionary zpracování klíčů, a také zajistit, aby názvové skopy XAML nebyly použity na ResourceDictionary nadřazené prvky.

FrameworkTemplate a Style implementujte INameScope prostřednictvím explicitních definic rozhraní. Explicitní implementace umožňují, aby se tyto názvové skopy XAML chovaly konvenčně při přístupu prostřednictvím INameScope rozhraní, což je způsob, jakým jsou názvovéskopy XAML komunikovány interními procesy WPF. Ale explicitní definice rozhraní nejsou součástí konvenčního rozhraní API povrchu FrameworkTemplate a Style, protože zřídka potřebujete volat INameScope metody on FrameworkTemplate a Style přímo, a místo toho byste použili jiné rozhraní API, jako GetTemplateChildje .

Následující třídy definují vlastní názvovýscope XAML pomocí System.Windows.NameScope pomocné třídy a připojují se k implementaci XAML namescope prostřednictvím NameScope.NameScope připojené vlastnosti:

Viz také