Zakresy nazw WPF XAML

XAML Zakresy nazw WPF to koncepcja, która identyfikuje obiekty zdefiniowane w języku XAML. Nazwy w namescope języka XAML mogą służyć do ustanawiania relacji między nazwami obiektów zdefiniowanymi w języku XAML a ich odpowiednikami wystąpień w drzewie obiektów. Zazwyczaj Zakresy nazw WPF języka XAML w WPF kodzie zarządzanym są tworzone podczas ładowania poszczególnych katalogów głównych stron XAML dla aplikacji XAML. KOD XAML Zakresy nazw WPF jako obiekt programistyczny jest definiowany przez INameScope interfejs i jest również zaimplementowany przez klasę praktyczną NameScope .

Zakresy nazw WPF w załadowanych aplikacjach XAML

W szerszym kontekście programowania lub nauki komputerowym koncepcje programowania często obejmują zasadę unikatowego identyfikatora lub nazwy, która może być używana do uzyskiwania dostępu do obiektu. W przypadku systemów, które używają identyfikatorów lub nazw, namescope definiuje granice, w których proces lub technika będą przeszukiwane, jeśli zażądano obiektu o tej nazwie lub że są wymuszane ograniczenia unikatowości tożsamości nazw. Te ogólne zasady są prawdziwe w przypadku języka XAML Zakresy nazw WPF. W programie WPF Zakresy nazw WPF języka XAML są tworzone na elemencie głównym strony XAML podczas ładowania strony. Każda nazwa określona na stronie XAML rozpoczynająca się od elementu głównego strony jest dodawana do odpowiednich NameScope języka XAML.

W języku XAML WPF elementy, które są wspólnymi elementami głównymi (takie jak Page i Window ), zawsze kontrolują NAMESCOPE języka XAML. Jeśli element taki jak FrameworkElement lub FrameworkContentElement jest elementem głównym strony w znaczniku, XAML procesor dodaje element Page główny niejawnie, aby Page można było udostępnić działające namescope języka XAML.

Uwaga

Akcje kompilacji WPF tworzą namescope języka XAML dla produkcji XAML, nawet jeśli żadne Name x:Name atrybuty nie są zdefiniowane we wszystkich elementach XAML znacznika.

Jeśli spróbujesz użyć tej samej nazwy dwa razy w dowolnym namescope języka XAML, zostanie zgłoszony wyjątek. W przypadku języka XAML WPF, który zawiera kod i jest częścią skompilowanej aplikacji, wyjątek jest wywoływany w czasie kompilacji przez akcje kompilacji WPF, podczas tworzenia wygenerowanej klasy dla strony podczas początkowej kompilacji znaczników. W przypadku języka XAML, który nie jest kompilowany do znaczników przez żadną akcję kompilacji, wyjątki związane z problemami z namescope XAML mogą zostać zgłoszone podczas ładowania XAML. Projektanci XAML mogą również przewidzieć problemy namescope języka XAML w czasie projektowania.

Dodawanie obiektów do drzew obiektów środowiska uruchomieniowego

Moment, w którym kod XAML jest analizowany, wskazuje moment, w którym jest tworzony i definiowany namescope języka XAML WPF. W przypadku dodania obiektu do drzewa obiektów w punkcie w czasie po przeanalizowaniu kodu XAML, który wygenerował to drzewo, Name lub x:Name wartość w nowym obiekcie nie aktualizuje automatycznie informacji w języku XAML namescope. Aby dodać nazwę dla obiektu do elementu WPF XAML namescope po załadowaniu XAML, należy wywołać odpowiednią implementację RegisterName dla obiektu, który definiuje NAMESCOPE XAML, który jest zazwyczaj głównym katalogiem strony XAML. Jeśli nazwa nie jest zarejestrowana, do dodanego obiektu nie można odwoływać się za pomocą metod, takich jak FindName , i nie można użyć tej nazwy dla celów animacji.

Najbardziej typowym scenariuszem dla deweloperów aplikacji jest użycie RegisterName do rejestracji nazw w języku XAML namescope w bieżącym katalogu głównym strony. RegisterName jest częścią ważnego scenariusza dla scenorysów, które są obiektami docelowymi dla animacji. Aby uzyskać więcej informacji, zobacz Omówienie scenorysów.

Jeśli wywołasz RegisterName obiekt inny niż obiekt definiujący namescope języka XAML, nazwa jest wciąż zarejestrowana w kodzie XAML namescope, w którym znajduje się obiekt wywołujący w, tak jakby był wywoływany RegisterName w obiekcie języka XAML namescope.

Kod XAML Zakresy nazw WPF w kodzie

Możesz tworzyć i używać Zakresy nazw WPF języka XAML w kodzie. Interfejsy API i koncepcje związane z tworzeniem namescope języka XAML są takie same, nawet w przypadku czystego użycia kodu, ponieważ procesor XAML WPF używa tych interfejsów API i koncepcji, gdy przetwarzają one kod XAML. Pojęcia i interfejs API są przeznaczone głównie do znajdowania obiektów według nazwy w drzewie obiektów, które są zwykle zdefiniowane częściowo lub w całości w języku XAML.

W przypadku aplikacji, które są tworzone programowo, a nie z załadowanego kodu XAML, obiekt definiujący namescope XAML musi implementować lub INameScope być FrameworkElement FrameworkContentElement klasą pochodną, aby obsługiwała tworzenie namescope XAML w jego wystąpieniach.

Ponadto dla każdego elementu, który nie jest ładowany i przetwarzany przez procesor XAML, namescope XAML dla obiektu nie jest tworzony ani inicjowany domyślnie. Musisz jawnie utworzyć nowy kod XAML namescope dla każdego obiektu, który zamierza zarejestrować nazwy w późniejszym czasie. Aby utworzyć namescope XAML, należy wywołać metodę statyczną SetNameScope . Określ obiekt, który będzie jego właocicielem jako dependencyObject parametr, oraz nowe NameScope wywołanie konstruktora jako value parametr.

Jeśli obiekt dostarczony jako dependencyObject dla SetNameScope nie jest INameScope implementacją, FrameworkElement lub FrameworkContentElement wywołanie RegisterName dowolnego elementu podrzędnego nie będzie miało żadnego efektu. Jeśli nie można jawnie utworzyć nowego języka XAML namescope, wywołanie zostanie zgłoszone RegisterName jako wyjątek.

Przykład używania interfejsów API namescope języka XAML w kodzie można znaleźć w temacie Definiowanie zakresu nazw.

Zakresy nazw WPF języka XAML w stylach i szablonach

Style i szablony w programie WPF zapewniają możliwość wielokrotnego użycia i ponownego zastosowania zawartości w prosty sposób. Jednak style i szablony mogą również zawierać elementy z nazwami XAML zdefiniowanymi na poziomie szablonu. Ten sam szablon może być używany wiele razy na stronie. Z tego powodu style i szablony definiują własne Zakresy nazw WPF języka XAML niezależnie od lokalizacji w drzewie obiektów, w której zastosowano styl lub szablon.

Rozpatrzmy następujący przykład:

<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>

Ten sam szablon jest stosowany do dwóch różnych przycisków. Jeśli szablony nie zawierały dyskretnych Zakresy nazw wpfów XAML, TheBorder Nazwa użyta w szablonie spowodowałaby kolizję nazw w NAMESCOPE XAML. Każde wystąpienie szablonu ma własne namescope języka XAML, więc w tym przykładzie każdy kod XAML namescope szablonu, który będzie zawierał dokładnie jedną nazwę.

Style również definiują własne namescope kodu XAML, aby części scenorysów mogły mieć przypisane określone nazwy. Te nazwy umożliwiają kontrolę określonych zachowań, które będą elementami docelowymi tej nazwy, nawet jeśli szablon został ponownie zdefiniowany w ramach dostosowywania kontroli.

Ze względu na oddzielne zakresy nazw WPF języka XAML wyszukiwanie nazwanych elementów w szablonie jest trudniejsze niż znalezienie elementu o nazwie nieopartego na szablonie na stronie. Najpierw należy określić zastosowany szablon, pobierając Template wartość właściwości kontrolki, w której jest stosowany szablon. Następnie należy wywołać wersję szablonu FindName , przekazując kontrolkę, w której szablon został zastosowany jako drugi parametr.

Jeśli jesteś autorem kontrolki i tworzysz Konwencję, w której konkretny nazwany element w zastosowanym szablonie jest obiektem docelowym dla zachowania zdefiniowanego przez sam formant, możesz użyć GetTemplateChild metody z kodu implementacji formantu. GetTemplateChildMetoda jest chroniona, dlatego tylko autor formantu ma do niego dostęp.

Jeśli pracujesz z poziomu szablonu i chcesz uzyskać dostęp do NameScope języka XAML, w którym szablon jest zastosowany, Pobierz wartość TemplatedParent , a następnie Wywołaj ją FindName . Przykładem działania w ramach szablonu jest zapisanie implementacji programu obsługi zdarzeń, w której zdarzenie zostanie podniesione z elementu w zastosowaniu szablonu.

FrameworkElement ma FindName RegisterName metody i UnregisterName . Jeśli obiekt wywołuje te metody na własność namescope języka XAML, metody wywołują metody odpowiednich namescope XAML. W przeciwnym razie element nadrzędny jest sprawdzany, aby zobaczyć, czy jest właścicielem namescope języka XAML, i ten proces jest kontynuowany cyklicznie do momentu znalezienia namescope XAML (z powodu zachowania procesora XAML, zagwarantowany jest namescope XAML w katalogu głównym). FrameworkContentElement ma analogiczne zachowania, z wyjątkiem tego, że nie FrameworkContentElement będzie nigdy własnością namescope języka XAML. Metody istnieją tak, FrameworkContentElement Aby wywołania mogły być przekazywane ostatecznie do FrameworkElement elementu nadrzędnego.

SetNameScope służy do mapowania nowego namescope języka XAML na istniejący obiekt. Możesz wywołać SetNameScope więcej niż jeden raz, aby zresetować lub wyczyścić NAMESCOPE XAML, ale nie jest to typowe użycie. Ponadto GetNameScope nie jest zazwyczaj używany w kodzie.

Implementacje języka XAML namescope

Następujące klasy implementują się INameScope bezpośrednio:

ResourceDictionary nie używa nazw XAML ani Zakresy nazw WPF; Zamiast tego używa kluczy, ponieważ jest implementacją słownika. Jedyną przyczyną, która ResourceDictionary implementuje, INameScope jest to, że może ona zgłaszać wyjątki do kodu użytkownika, który ułatwia wyjaśnienie rozróżnienia między prawdziwym namescope języka XAML i jak ResourceDictionary obsługuje klucze, a także gwarantuje, że zakresy nazw WPF XAML nie są stosowane do ResourceDictionary elementów nadrzędnych.

FrameworkTemplate i Style implementowanie INameScope za poorednictwem jawnych definicji interfejsu. Jawne implementacje zezwalają, aby te zakresy nazw WPF języka XAML działały zwyczajowo, gdy dostęp do nich odbywa się za pomocą INameScope interfejsu, co jest sposobem komunikacji Zakresy nazw WPF języka XAML przez WPF procesy wewnętrzne. Jednak jawne definicje interfejsu nie są częścią konwencjonalnej powierzchni interfejsu API FrameworkTemplate i Style , ponieważ rzadko trzeba wywołać INameScope metody w FrameworkTemplate i Style bezpośrednio, a zamiast tego użyć innego interfejsu API, takiego jak GetTemplateChild .

Poniższe klasy definiują własne namescope języka XAML, używając System.Windows.NameScope klasy pomocnika i łącząc się z implementacją namescope języka XAML za pomocą NameScope.NameScope dołączonej właściwości:

Zobacz też