Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Zakres nazw XAML przechowuje relacje między zdefiniowanymi przez język XAML nazwami obiektów i ich odpowiednikami wystąpień. Ta koncepcja jest podobna do szerszego znaczenia terminu namescope w innych językach programowania i technologiach.
Jak zdefiniowano zakresy nazw XAML
Nazwy w przestrzeniach nazw XAML umożliwiają kodowi użytkowemu odwoływanie się do obiektów, które zostały początkowo zadeklarowane w języku XAML. Wewnętrzny wynik analizowania kodu XAML polega na tym, że środowisko uruchomieniowe tworzy zestaw obiektów, które zachowują niektóre lub wszystkie relacje, które te obiekty miały w deklaracjach XAML. Te relacje są zachowywane jako określone właściwości obiektu utworzonych obiektów lub są widoczne dla metod narzędziowych w interfejsach API modelu programowania.
Najbardziej typowe użycie nazwy w zakresie nazw XAML to bezpośrednie odniesienie do instancji obiektu, co jest umożliwione przez kompilację znaczników jako akcję budowania projektu, w połączeniu z wygenerowaną metodą InitializeComponent w szablonach klasy częściowej.
Możesz również użyć metody pomocniczej FindName samodzielnie podczas działania, aby zwrócić referencję do obiektów zdefiniowanych z nazwą w znacznikach XAML.
Więcej informacji na temat akcji kompilacji i języka XAML
Technicznie rzecz biorąc, sam XAML przechodzi przez kompilację znaczników w tym samym czasie, co XAML i klasa częściowa, którą definiuje dla zaplecza kodu, są kompilowane razem. Każdy element obiektu z atrybutem Name lub x:Name zdefiniowanym w znaczniku generuje pole wewnętrzne o nazwie zgodnej z nazwą XAML. To pole jest początkowo puste. Następnie klasa generuje metodę InitializeComponent , która jest wywoływana dopiero po załadowaniu całego kodu XAML. W ramach logiki InitializeComponent każde pole wewnętrzne jest następnie wypełniane wartością zwracaną przez findName dla równoważnego ciągu nazwy. Tę infrastrukturę można obserwować samodzielnie, przeglądając pliki ".g" (wygenerowane) utworzone dla każdej strony XAML w podfolderze /obj projektu aplikacji Środowiska uruchomieniowego systemu Windows po kompilacji. Możesz również zobaczyć pola i metodę InitializeComponent jako elementy członkowskie wynikowych zestawów, jeśli zastosujesz refleksję lub w inny sposób przeanalizujesz zawartość ich języka interfejsu.
Uwaga / Notatka
W szczególności w przypadku aplikacji rozszerzeń składników języka Visual C++ (C++/CX) pole zapasowe dla odwołania x:Name nie jest tworzone dla elementu głównego pliku XAML. Jeśli musisz odwołać się do obiektu głównego z kodu C++/CX, użyj innych interfejsów API lub przechodzenia po drzewie. Na przykład można wywołać metodę FindName dla znanego nazwanego elementu podrzędnego, a następnie wywołać metodę Parent.
Tworzenie obiektów w czasie wykonywania przy użyciu XamlReader.Load
Kod XAML może być również używany jako dane wejściowe ciągu dla metody XamlReader.Load , która działa analogicznie do początkowej operacji analizy źródła XAML. XamlReader.Load tworzy nowe, niezależne drzewo obiektów podczas działania programu. Odłączone drzewo można następnie dołączyć do pewnego punktu w głównym drzewie obiektów. Musisz jawnie połączyć utworzone drzewo obiektów, dodając je do kolekcji właściwości zawartości, takiej jak Elementy podrzędne, lub ustawiając inną właściwość, która przyjmuje wartość obiektu (na przykład ładując nową ImageBrush dla właściwości Fill).
Implikacje związane z zakresem nazw XAML podczas użycia XamlReader.Load
Wstępny zakres nazw XAML zdefiniowany przez nowe drzewo obiektów utworzone przez element XamlReader.Load oblicza wszystkie zdefiniowane nazwy w podanym kodzie XAML pod kątem unikatowości. Jeśli nazwy w podanym języku XAML nie są w tym momencie unikatowe wewnętrznie, funkcja XamlReader.Load zgłasza wyjątek. Odłączone drzewo obiektów nie próbuje scalić swojego zakresu nazw XAML z głównym zakresem nazw XAML aplikacji, gdy zostanie połączone z głównym drzewem obiektów aplikacji. Po połączeniu drzew, aplikacja ma ujednolicone drzewo obiektów, ale to drzewo zawiera dyskretne przestrzenie nazw XAML. Podziały występują w punktach połączenia między obiektami, w których ustawiono pewną właściwość na wartość zwracaną z wywołania XamlReader.Load.
Komplikacją posiadania dyskretnych i odłączonych zakresów nazw XAML jest to, że wywołania metody FindName oraz bezpośrednie odwołania do zarządzanych obiektów przestają działać w ramach ujednoliconego zakresu nazw XAML. Zamiast tego, konkretny obiekt, na którym wywołano FindName, oznacza zakres, przy czym zakres jest zakresem nazw XAML, w którym znajduje się obiekt wywołujący. W przypadku bezpośredniego odwołania do obiektu zarządzanego zakres jest implikowany przez klasę, w której istnieje kod. Zazwyczaj kod związany z interakcją w czasie wykonywania "strony" zawartości aplikacji istnieje w klasie częściowej, która stanowi kopię zapasową głównej "strony", a zatem zakres nazw XAML jest głównym zakresem nazw XAML.
Jeśli wywołasz metodę FindName, aby pobrać nazwany obiekt w głównym zakresie nazw XAML, metoda nie znajdzie obiektów z dyskretnego zakresu nazw XAML utworzonego przez XamlReader.Load. Przeciwnie, jeśli wywołasz FindName z obiektu uzyskanego z dyskretnego zakresu nazw XAML, metoda nie znajdzie obiektów w głównym zakresie nazw XAML.
Ten dyskretny problem z przestrzenią nazw XAML ma wpływ tylko na znajdowanie obiektów według nazwy w przestrzeniach nazw XAML podczas używania wywołania FindName.
Aby uzyskać odwołania do obiektów zdefiniowanych w innym kodzie nazw XAML, można użyć kilku technik:
- Przemierz całe drzewo w dyskretnych krokach, przy użyciu właściwości Parent i/lub znanych kolekcji w strukturze drzewa obiektów (na przykład kolekcja zwrócona przez Panel.Children).
- Jeśli wywołujesz z oddzielnego zakresu nazw XAML i chcesz odwołać się do głównego zakresu nazw XAML, zawsze łatwo uzyskać referencję do głównego okna, które jest obecnie wyświetlane. Główny element wizualny (główny element XAML, znany również jako źródło zawartości) można uzyskać z bieżącego okna aplikacji za pomocą jednego wiersza kodu, wywołując
Window.Current.Content. Następnie możesz rzutować na FrameworkElement i wywołać FindName w ramach tego zakresu. - Jeśli wywołujesz wywołanie z głównego zakresu nazw XAML i chcesz, aby obiekt znajdował się w dyskretnym zakresie nazw XAML, najlepszym rozwiązaniem jest zaplanowanie z wyprzedzeniem w kodzie i zachowanie odwołania do obiektu zwróconego przez XamlReader.Load , a następnie dodanego do głównego drzewa obiektów. Ten obiekt jest teraz prawidłowym obiektem do wywoływania funkcji FindName w dyskretnym zakresie nazw XAML. Ten obiekt można zachować jako zmienną globalną lub przekazać go w inny sposób przy użyciu parametrów metody.
- Można całkowicie uniknąć zajmowania się nazwami i zakresem nazw XAML, badając drzewo wizualne. Interfejs API VisualTreeHelper umożliwia przechodzenie przez drzewo wizualne w kontekście obiektów nadrzędnych i kolekcji podrzędnych, wyłącznie na podstawie pozycji i indeksu.
Zakresy nazw XAML w szablonach
Szablony w języku XAML zapewniają możliwość ponownego użycia i ponownego zastosowania zawartości w prosty sposób, ale szablony mogą również zawierać elementy z nazwami zdefiniowanymi na poziomie szablonu. Ten sam szablon może być używany wiele razy na stronie. Z tego powodu szablony definiują własne zakresy nazw XAML niezależnie od strony zawierającej, na której jest stosowany styl lub szablon. Rozważmy 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="MyTemplate">
....
<TextBlock x:Name="MyTextBlock" />
</ControlTemplate>
</Page.Resources>
<StackPanel>
<SomeControl Template="{StaticResource MyTemplate}" />
<SomeControl Template="{StaticResource MyTemplate}" />
</StackPanel>
</Page>
W tym miejscu ten sam szablon jest stosowany do dwóch różnych kontrolek. Jeśli szablony nie miałyby oddzielnych przestrzeni nazw XAML, nazwa "MyTextBlock" używana w szablonie spowodowałaby kolizję nazw. Każde wystąpienie szablonu ma własny zakres nazw XAML, więc w tym przykładzie zakres nazw XAML dla każdego wystąpienia szablonu zawiera dokładnie jedną nazwę. Jednak główny zakres nazw XAML nie zawiera nazwy z jednego z szablonów.
Ze względu na oddzielne zakresy nazw XAML znalezienie nazwanych elementów w szablonie z zakresu strony, na której zastosowano szablon, wymaga innej techniki. Zamiast wywoływać FindName w drzewie obiektów, najpierw uzyskaj obiekt, do którego zastosowano szablon, a następnie wywołaj metodę GetTemplateChild. Jeśli jesteś autorem kontrolki i generujesz konwencję, w której określony nazwany element w zastosowanym szablonie jest elementem docelowym zachowania zdefiniowanego przez samą kontrolkę, możesz użyć metody GetTemplateChild z kodu implementacji kontrolki. Metoda GetTemplateChild jest chroniona, więc tylko autor kontroli ma do niej dostęp. Istnieją również konwencje, które autorzy kontrolek powinni przestrzegać w celu nadania nazw częściom i częściom szablonu oraz zgłaszaniu ich jako wartości atrybutów zastosowanych do klasy kontrolnej. Ta technika sprawia, że nazwy ważnych części można odnaleźć w celu kontrolowania użytkowników, którzy mogą chcieć zastosować inny szablon, co wymagałoby zastąpienia nazwanych części w celu zachowania funkcjonalności kontroli.
Tematy pokrewne
Windows developer