Szczegóły składni XAML
W tym temacie zdefiniowano terminy używane do opisywania elementów składni JĘZYKA XAML. Te terminy są często używane w pozostałej części tej dokumentacji, zarówno dla dokumentacji WPF, jak i dla innych platform, które używają języka XAML, lub podstawowych pojęć XAML włączonych przez obsługę języka XAML na poziomie System.Xaml. W tym temacie rozszerzono podstawową terminologię wprowadzona w temacie XAML w WPF.
Specyfikacja języka XAML
Zdefiniowana tutaj terminologia składni XAML jest również zdefiniowana lub przywołyowana w specyfikacji języka XAML. XAML to język oparty na języku XML, który jest kontynuacją lub rozszerzeniem reguł strukturalnych XML. Niektóre terminologia jest udostępniana lub jest oparta na terminologii często używanej podczas opisywania języka XML lub modelu obiektu dokumentu XML.
Aby uzyskać więcej informacji na temat specyfikacji języka XAML, pobierz plik [MS-XAML] z Centrum pobierania Microsoft.
XAML i CLR
XAML to język znaczników. Środowisko uruchomieniowe języka wspólnego (CLR) zgodnie z jego nazwą umożliwia wykonywanie w czasie wykonywania. Język XAML nie jest sam w sobie jednym z typowych języków, które są bezpośrednio używane przez środowisko uruchomieniowe CLR. Zamiast tego można myśleć o języku XAML jako o wspieraniu własnego systemu typów. Konkretny system analizowania XAML, który jest używany przez WPF, jest zbudowany na systemie clr i typu CLR. Typy XAML są mapowane na typy CLR w celu wystąpienia reprezentacji czasu działania podczas analizowania kodu XAML dla WPF. Z tego powodu pozostała część dyskusji o składni w tym dokumencie będzie zawierać odwołania do systemu typów CLR, mimo że równoważne dyskusje o składni w specyfikacji języka XAML nie mają zastosowania. (Na poziomie specyfikacji języka XAML typy XAML mogą być mapowane na dowolny inny system typów, który nie musi być clr, ale wymagałoby to utworzenia i użycia innego parsera XAML).
Składowe typów i dziedziczenia klas
Właściwości i zdarzenia wyświetlane jako elementy członkowskie XAML typu WPF są często dziedziczone z typów podstawowych. Rozważmy na przykład ten przykład: <Button Background="Blue" .../>. Właściwość Background nie jest natychmiast zadeklarowaną Button właściwością klasy, jeśli chcesz przyjrzeć się definicji klasy, wynikom odbicia lub dokumentacji. Zamiast tego jest Background dziedziczona z klasy Control bazowej.
Zachowanie dziedziczenia klas elementów XAML WPF jest znaczącym odejściem od wymuszania przez schemat interpretacji znaczników XML. Dziedziczenie klas może stać się złożone, szczególnie gdy pośrednie klasy bazowe są abstrakcyjne lub gdy są zaangażowane interfejsy. Jest to jeden z powodów, dla których zestaw elementów XAML i ich dozwolone atrybuty są trudne do reprezentowania dokładnie i całkowicie przy użyciu typów schematu, które są zwykle używane do programowania XML, takich jak DTD lub XSD format. Innym powodem jest to, że funkcje rozszerzalności i mapowania typów języka XAML wykluczają kompletność dowolnej stałej reprezentacji dozwolonych typów i elementów członkowskich.
Składnia elementu obiektu
Składnia elementu obiektu to składnia znaczników XAML, która intuiuje klasę lub strukturę CLR przez zadeklarowanie elementu XML. Ta składnia przypomina składnię elementów innych języków znaczników, takich jak HTML. Składnia elementu obiektu rozpoczyna się od lewego nawiasu kątowego (<), po którym natychmiast następuje nazwa typu klasy lub struktury, która jest dawana. Zero lub więcej spacji może być zgodne z nazwą typu, a zero lub więcej atrybutów może być również zadeklarowane w elemencie obiektu, z co najmniej jedną spacją oddzielającą każdą parę atrybut name="value". Na koniec musi być spełnione jedno z następujących:
Element i tag muszą być zamknięte ukośnikiem (/), po którym następuje prawy nawias kątowy (>).
Tag otwierający musi być uzupełniony prawym nawiasem kątowym (>). Inne elementy obiektu, elementy właściwości lub tekst wewnętrzny mogą być zgodne z tagiem otwierającym. Dokładnie, jaka zawartość może być zawarta w tym miejscu, jest zwykle ograniczona przez model obiektów elementu. Równoważny tag zamykający elementu obiektu musi również istnieć w odpowiednim zagnieżdżania i równoważyć z innymi parami tagów otwierających i zamykających.
Język XAML zaimplementowany przez platformę .NET zawiera zestaw reguł, które mapuje elementy obiektu na typy, atrybuty na właściwości lub zdarzenia oraz przestrzenie nazw XAML na przestrzenie nazw CLR oraz zestaw. W przypadku platform WPF i .NET elementy obiektu XAML są mapowane na typy .NET zgodnie z definicją w zestawach, do których się odwoływuje, a atrybuty są mapowane na elementy członkowskie tych typów. Odwołując się do typu CLR w języku XAML, masz również dostęp do dziedziczonych elementów członkowskich tego typu.
Na przykład poniższy przykład Button to składnia elementu obiektu, która instancji nowego wystąpienia klasy, a Name także określa atrybut i wartość dla tego atrybutu:
<Button Name="CheckoutButton"/>
Poniższy przykład to składnia elementu obiektu, która zawiera również składnię właściwości zawartości XAML. Tekst wewnętrzny zawarty w obiekcie zostanie użyty do ustawienia właściwości TextBox zawartości XAML , Text.
<TextBox>This is a Text Box</TextBox>
Modele zawartości
Klasa może obsługiwać użycie jako element obiektu XAML pod względem składni, ale ten element będzie działać prawidłowo tylko w aplikacji lub na stronie, gdy zostanie umieszczony w oczekiwanej pozycji ogólnego modelu zawartości lub drzewa elementów. Na przykład klasę MenuItem należy zwykle MenuBase umieścić tylko jako klasę podrzędną klasy pochodnej, takiej jak Menu. Modele zawartości dla określonych elementów są udokumentowane jako część uwag na stronach klas dla kontrolek i innych klas WPF, które mogą być używane jako elementy XAML.
Właściwości elementów obiektu
Właściwości w języku XAML są ustawiane przy użyciu różnych możliwych składni. Składnia, której można użyć dla określonej właściwości, będzie się różnić w zależności od charakterystyki systemu typów podstawowych właściwości, która jest ustawiana.
Ustawiając wartości właściwości, można dodawać cechy lub cechy do obiektów w momencie ich istnienia na wykresie obiektów czasu uruchomienia. Początkowy stan utworzonego obiektu z elementu obiektu jest oparty na zachowaniu konstruktora bez parametrów. Zazwyczaj aplikacja używa czegoś innego niż całkowicie domyślne wystąpienie dowolnego obiektu.
Składnia atrybutów (właściwości)
Składnia atrybutu to składnia znaczników XAML, która ustawia wartość właściwości przez zadeklarowanie atrybutu w istniejącym elemencie obiektu. Nazwa atrybutu musi odpowiadać nazwie elementu członkowskiego CLR właściwości klasy, która stanowi kopię zapasową odpowiedniego elementu obiektu. Po nazwie atrybutu następuje operator przypisania (=). Wartość atrybutu musi być ciągiem ujętym w cudzysłowy.
Uwaga
Możesz użyć cudzysłowów naprzemiennych, aby umieścić znak cudzysłowu literału w obrębie atrybutu. Na przykład można użyć a cudzysłowów pojedynczych jako środka do zadeklarowania ciągu zawierającego znak podwójnego cudzysłowu. Bez względu na to, czy używasz cudzysłowu pojedynczego, czy podwójnego, należy użyć pasującej pary do otwierania i zamykania ciągu wartości atrybutu. Dostępne są również sekwencje ucieczki lub inne techniki do pracy z ograniczeniami znaków narzuconym przez określoną składnię XAML. Zobacz Jednostki znaków XML i XAML.
Aby można było ustawić za pomocą składni atrybutów, właściwość musi być publiczna i musi być zapisywalna. Wartość właściwości w systemie typów kopii zapasowej musi być typem wartości lub typem referencyjnym, który może być wystąpieniami procesora XAML lub do których może się odwoływać podczas uzyskiwania dostępu do odpowiedniego typu kopii zapasowej.
W przypadku zdarzeń WPF XAML zdarzenie, które jest przywołyowane jako nazwa atrybutu, musi być publiczne i mieć publicznego delegata.
Właściwość lub zdarzenie musi być składową klasy lub struktury, która jest owana przez zawierający element obiektu.
Przetwarzanie wartości atrybutów
Wartość ciągu zawarta w otwierających i zamykających cudzysłowach jest przetwarzana przez procesor XAML. W przypadku właściwości domyślne zachowanie przetwarzania jest określane przez typ bazowej właściwości CLR.
Wartość atrybutu jest wypełniana przy użyciu jednej z następujących kolejności przetwarzania:
Jeśli procesor XAML MarkupExtensionnapotka nawias klamrowy lub element obiektu, który pochodzi od , to odwołanie do rozszerzenia znaczników jest oceniane jako pierwsze zamiast przetwarzania wartości jako ciągu, a obiekt zwracany przez rozszerzenie znaczników jest używany jako wartość. W wielu przypadkach obiekt zwracany przez rozszerzenie znaczników będzie odwołaniem do istniejącego obiektu lub wyrażeniem, które nie będzie oceniać do czasu uruchomienia i nie jest nowo utworzonym obiektem wystąpienia.
TypeConverterJeśli właściwość jest zadeklarowana z atrybutem lub TypeConvertertyp wartości tej właściwości jest zadeklarowany z atrybutem , wartość ciągu atrybutu jest przesłana do konwertera typu jako dane wejściowe konwersji, a konwerter zwróci nowe wystąpienie obiektu.
Jeśli nie ma właściwości TypeConverter, podejmowana jest próba bezpośredniej konwersji na typ właściwości. Ten końcowy poziom jest bezpośrednią konwersją na wartość natywną parsera między typami pierwotnymi języka XAML lub sprawdzeniem nazw nazwanych stałych w wyliczeniu (parser uzyskuje dostęp do pasujących wartości).
Wartości atrybutów wyliczenia
Wyliczenia w języku XAML są przetwarzane wewnętrznie przez parsery XAML, a elementy członkowskie wyliczenia należy określić, określając nazwę ciągu jednej z nazwanych stałych wyliczenia.
W przypadku wartości wyliczenia innych niżlag zachowanie natywne to przetwarzanie ciągu wartości atrybutu i rozwiązywanie go do jednej z wartości wyliczenia. Wyliczenie nie jest określone w formacie Enumeration (Wyliczenie). Wartość, tak jak w kodzie. Zamiast tego należy określić tylko wartość, a wyliczenie jest wywnioskowane przez typ ustawianej właściwości. Jeśli określisz atrybut w wyliczeniu. Formularz wartości nie zostanie poprawnie rozpoznany.
W przypadku wyliczeń flagowych zachowanie jest oparte na Enum.Parse metodzie . Można określić wiele wartości dla wyliczenia flagowego, oddzielając każdą wartość przecinkiem. Nie można jednak łączyć wartości wyliczenia, które nie są flagowe. Na przykład nie można użyć składni przecinka Trigger , aby spróbować utworzyć, który działa na wielu warunkach wyliczenia nonflag:
<!--This will not compile, because Visibility is not a flagwise enumeration.-->
...
<Trigger Property="Visibility" Value="Collapsed,Hidden">
<Setter ... />
</Trigger>
...
Flagowe wyliczenia, które obsługują atrybuty, które można ustawić w JĘZYKu XAML, są rzadkie w WPF. Jednak jednym z takich wyliczeń jest StyleSimulations. Można na przykład użyć składni atrybutu rozdzielanego przecinkami flagowo Glyphs , aby zmodyfikować przykład podany w uwagi dla klasy; StyleSimulations = "BoldSimulation" może stać się StyleSimulations = "BoldSimulation,ItalicSimulation". KeyBinding.Modifiers jest inną właściwością, w której można określić więcej niż jedną wartość wyliczenia. Jednak ta właściwość jest szczególnym przypadekem, ModifierKeys ponieważ wyliczenie obsługuje własny konwerter typów. Konwerter typów dla modyfikatorów używa znaku plus (+) jako ogranicznika, a nie przecinka (,). Ta konwersja obsługuje bardziej tradycyjną składnię do reprezentowania kombinacji klawiszy w programowaniu Windows Microsoft, na przykład "Ctrl+Alt".
Odwołania do właściwości i nazwy członka zdarzenia
Podczas określania atrybutu można odwoływać się do dowolnej właściwości lub zdarzenia, które istnieje jako element członkowski typu CLR, który został narysowany dla zawierającego elementu obiektu.
Można też odwoływać się do dołączonej właściwości lub dołączonego zdarzenia, niezależnie od zawierającego elementu obiektu. (Dołączone właściwości zostały omówione w kolejnej sekcji).
Można również nazwać dowolne zdarzenie z dowolnego obiektu, który jest dostępny za pośrednictwem domyślnej przestrzeni nazw przy użyciu typeName. nazwa zdarzenia częściowo kwalifikowana; Ta składnia obsługuje dołączanie programów obsługi dla zdarzeń trasowane, gdzie program obsługi jest przeznaczony do obsługi routingu zdarzeń z elementów nadrzędnych, ale element nadrzędny nie ma również tego zdarzenia w swojej tabeli elementów członkowskich. Ta składnia przypomina składnię dołączonego zdarzenia, ale zdarzenie w tym miejscu nie jest zdarzeniem dołączonym. Zamiast tego odwołujesz się do zdarzenia z kwalifikowaną nazwą. Aby uzyskać więcej informacji, zobacz Routed Events Overview (Omówienie zdarzeń trasowych).
W niektórych scenariuszach nazwy właściwości są czasami podane jako wartość atrybutu, a nie jako nazwa atrybutu. Ta nazwa właściwości może również zawierać kwalifikatory, takie jak właściwość określona w formularzu ownerType. dependencyPropertyName. Ten scenariusz jest powszechny podczas pisania stylów lub szablonów w języku XAML. Reguły przetwarzania dla nazw właściwości podanych jako wartość atrybutu są różne i podlegają typowi ustawianej właściwości lub zachowaniom określonych podsystemów WPF. Aby uzyskać szczegółowe informacje, zobacz Styleing and Templating (Style i szablonów).
Innym zastosowaniem nazw właściwości jest to, gdy wartość atrybutu opisuje relację właściwości. Ta funkcja jest używana do powiązania danych i obiektów docelowych storyboard oraz jest włączana PropertyPath przez klasę i konwerter typów. Aby uzyskać bardziej szczegółowy opis semantyki wyszukiwania, zobacz PropertyPath XAML Syntax (Składnia xaml PropertyPath).
Składnia elementu właściwości
Składnia elementu właściwości jest składnią, która odbiega nieco od podstawowych reguł składni XML dla elementów. W języku XML wartość atrybutu jest de facto ciągiem, a jedyną możliwą odmianą jest format kodowania ciągów, który jest używany. W języku XAML można przypisać inne elementy obiektu jako wartość właściwości. Ta możliwość jest włączona za pomocą składni elementu właściwości. Zamiast właściwości określonej jako atrybut w tagu elementu, właściwość jest określana przy użyciu otwierającego tagu elementu w elemencie elementTypeName. propertyName form, wartość właściwości jest określona w elemencie , a następnie element właściwości jest zamykany.
W szczególności składnia rozpoczyna się od lewego nawiasu kątowego (<), po którym natychmiast następuje nazwa typu klasy lub struktury, w której znajduje się składnia elementu właściwości. Po niej natychmiast następuje pojedyncza kropka (.), następnie nazwa właściwości, a następnie prawy nawias kątowy (>). Podobnie jak w przypadku składni atrybutów, ta właściwość musi istnieć w obrębie zadeklarowanych publicznych elementów członkowskich określonego typu. Wartość, która ma zostać przypisana do właściwości, jest zawarta w elemencie właściwości. Zazwyczaj wartość jest podana jako co najmniej jeden element obiektu, ponieważ określanie obiektów jako wartości jest scenariuszem, w którym składnia elementu właściwości jest przeznaczona do adresowania. Na koniec równoważny tag zamykający określający ten sam elementTypeName. Należy podać kombinację propertyName we właściwym zagnieżdżeniu i równoważyć z innymi tagami elementów.
Na przykład poniżej przedstawiono składnię elementu właściwości dla ContextMenu właściwości elementu Button.
<Button>
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="1">First item</MenuItem>
<MenuItem Header="2">Second item</MenuItem>
</ContextMenu>
</Button.ContextMenu>
Right-click me!</Button>
Wartość w elemencie właściwości może być również podana jako tekst wewnętrzny, w przypadkach, gdy określony typ właściwości jest typem wartości pierwotnej, Stringtakim jak , lub wyliczeniem, w którym określono nazwę. Te dwa zastosowania są nieco nietypowe, ponieważ każdy z tych przypadków może również używać prostszej składni atrybutów. Jeden ze scenariuszy wypełniania elementu właściwości ciągiem jest dla właściwości, które nie są właściwością zawartości XAML, ale są nadal używane do reprezentacji tekstu interfejsu użytkownika, a w tym tekście interfejsu użytkownika muszą pojawić się konkretne elementy odstępu, takie jak linefeeds. Składnia atrybutów nie może zachować elementów liniowych, ale składnia elementu właściwości może, o ile znaczące zachowywanie białych spacji jest aktywne (aby uzyskać szczegółowe informacje, zobacz Przetwarzanie białych spacji w XAML). Innym scenariuszem jest zastosowanie dyrektywy x:Uid do elementu właściwości i oznaczenie jej jako wartości, która powinna być zlokalizowane w wyjściowym pliku BAML WPF lub za pomocą innych technik.
Element właściwości nie jest reprezentowany w drzewie logicznym WPF. Element właściwości jest po prostu określonej składni do ustawiania właściwości i nie jest elementem, który ma wystąpienie lub obiekt kopię zapasową. (Aby uzyskać szczegółowe informacje na temat koncepcji drzewa logicznego, zobacz Drzewa w WPF).
W przypadku właściwości, w których obsługiwana jest składnia atrybutu i elementu właściwości, te dwie składnie zwykle mają taki sam wynik, chociaż subtelności, takie jak obsługa białych spacji, mogą się nieznacznie różnić między składniami.
Składnia kolekcji
Specyfikacja XAML wymaga implementacji procesora XAML w celu zidentyfikowania właściwości, w których typ wartości jest kolekcją. Ogólna implementacja procesora XAML na .NET jest oparta na kodzie zarządzanym i clr oraz identyfikuje typy kolekcji za pomocą jednej z następujących czynności:
Typ implementuje .IList
Typ implementuje .IDictionary
Typ pochodzi od elementu Array (aby uzyskać więcej informacji na temat tablic w języku XAML, zobacz x:Array Markup Extension (Rozszerzenie znaczników x:Array).
Jeśli typ właściwości jest kolekcją, wówczas wywnioskowana kolekcja nie musi być określona w znaczniku jako element obiektu. Zamiast tego elementy, które mają stać się elementami w kolekcji, są określane jako co najmniej jeden element podrzędny elementu właściwości. Każdy taki element jest oceniany jako obiekt podczas ładowania i dodawany Add do kolekcji przez wywołanie metody kolekcji implikacji. Na przykład właściwość przyjmuje Triggers wyspecjalizowany Style typ kolekcji TriggerCollection, który implementuje .IList Nie jest konieczne, aby utworzyć wystąpienia elementu TriggerCollection obiektu w znacznikach. Zamiast tego należy określić co TriggerStyle.Triggers najmniej jeden element jako elementy w elemencie właściwości, Trigger gdzie (lub klasa pochodna) jest typem oczekiwanym jako typ elementu dla silnie typowego i niejawnego TriggerCollection.
<Style x:Key="SpecialButton" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="Button.IsMouseOver" Value="true">
<Setter Property = "Background" Value="Red"/>
</Trigger>
<Trigger Property="Button.IsPressed" Value="true">
<Setter Property = "Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
Właściwość może być zarówno typem kolekcji, jak i właściwością zawartości XAML dla tego typu i typów pochodnych, co omówiono w następnej sekcji tego tematu.
Niejawny element kolekcji tworzy element członkowski w reprezentacji drzewa logicznego, mimo że nie jest wyświetlany w znaczniku jako element. Zazwyczaj konstruktor typu nadrzędnego wykonuje tworzenie wystąpienia kolekcji, która jest jedną z jej właściwości, a początkowo pusta kolekcja staje się częścią drzewa obiektów.
Uwaga
Interfejsy listy ogólnej i słownika (IList<T> i IDictionary<TKey,TValue>) nie są obsługiwane w przypadku wykrywania kolekcji. Można jednak użyć klasy List<T> jako klasy bazowej, IList ponieważ implementuje ona bezpośrednio lub Dictionary<TKey,TValue> jako klasę bazową, ponieważ implementuje bezpośrednio IDictionary .
Na stronach odwołania .NET dla typów kolekcji ta składnia z celowym pominięciem elementu obiektu dla kolekcji jest czasami zanotowana w sekcjach składni XAML jako niejawna składnia kolekcji.
Z wyjątkiem elementu głównego, każdy element obiektu w pliku XAML zagnieżdżony jako element podrzędny innego elementu jest tak naprawdę elementem, który jest jednym lub w obu następujących przypadkach: elementem członkowskim niejawnej właściwości kolekcji jego elementu nadrzędnego lub elementem określającym wartość właściwości zawartości XAML dla elementu nadrzędnego (właściwości zawartości XAML zostaną omówione w następnej sekcji). Innymi słowy, relacja elementów nadrzędnych i elementów nadrzędnych na stronie znaczników jest tak naprawdę pojedynczym obiektem w katalogu głównym, a każdy element obiektu pod katalogiem głównym jest pojedynczym wystąpieniem, które zapewnia wartość właściwości elementu nadrzędnego, lub jednym z elementów w kolekcji, który jest również wartością właściwości typu kolekcji elementu nadrzędnego. Ta koncepcja pojedynczego elementu głównego jest wspólna dla kodu XML i jest często niesiena w zachowaniu interfejsów API, które ładują kod XAML, taki jak Load.
Poniższy przykład to składnia z elementem obiektu dla kolekcji (GradientStopCollection) określonym jawnie.
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
Należy pamiętać, że nie zawsze jest możliwe jawne zadeklarowanie kolekcji. Na przykład próba jawnego zadeklarowania w TriggerCollection pokazanym wcześniej przykładzie Triggers nie powiedzie się. Jawne deklarowanie kolekcji wymaga, aby klasa kolekcji obsługiła konstruktor bez parametrów i TriggerCollection nie ma konstruktora bez parametrów.
Właściwości zawartości XAML
Składnia zawartości XAML to składnia, która jest włączona tylko w klasach, które określają ContentPropertyAttribute element jako część deklaracji klasy. Element ContentPropertyAttribute odwołuje się do nazwy właściwości, która jest właściwością zawartości dla tego typu elementu (w tym klas pochodnych). W przypadku przetwarzania przez procesor XAML wszystkie elementy podrzędne lub tekst wewnętrzny znaleziony między tagami otwierającymi i zamykającymi elementu obiektu zostaną przypisane do wartości właściwości zawartości XAML dla tego obiektu. Można określić jawne elementy właściwości dla właściwości content, ale to użycie nie jest ogólnie widoczne w sekcjach składni JĘZYKA XAML w odwołaniach .NET. Technika jawna/szczegółowa ma sporadyczną wartość dla przejrzystości znaczników lub jako kwestia stylu na znaczników, ale zwykle celem właściwości zawartości jest usprawnienie na znaczników, tak aby elementy, które są intuicyjnie powiązane jako element nadrzędny-podrzędny, można było zagnieżdżać bezpośrednio. Tagi elementów właściwości dla innych właściwości elementu nie są przypisywane jako "zawartość" zgodnie z ścisłą definicją języka XAML; Są one przetwarzane wcześniej w kolejności przetwarzania parsera XAML i nie są uznawane za "zawartość".
Wartości właściwości zawartości XAML muszą być ciągłe
Wartość właściwości zawartości XAML musi być nadana całkowicie przed lub całkowicie po innych elementach właściwości w tym elemencie obiektu. Dotyczy to tego, czy wartość właściwości zawartości XAML jest określona jako ciąg, czy jako co najmniej jeden obiekt. Na przykład następujące znaczniki nie są analizowe:
<Button>I am a
<Button.Background>Blue</Button.Background>
blue button</Button>
Jest to niedozwolone, ponieważ jeśli ta składnia zostanie jawnie ustawiona przy użyciu składni elementu właściwości dla właściwości content, właściwość content zostanie ustawiona dwukrotnie:
<Button>
<Button.Content>I am a </Button.Content>
<Button.Background>Blue</Button.Background>
<Button.Content> blue button</Button.Content>
</Button>
Podobnie niedozwolonym przykładem jest sytuacja, gdy właściwość content jest kolekcją, a elementy podrzędne są przeplatane z elementami właściwości:
<StackPanel>
<Button>This example</Button>
<StackPanel.Resources>
<SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
</StackPanel.Resources>
<Button>... is illegal XAML</Button>
</StackPanel>
Połączone właściwości zawartości i składnia kolekcji
Aby można było akceptować więcej niż jeden element obiektu jako zawartość, typ właściwości content musi być w szczególności typem kolekcji. Podobnie jak w przypadku typów kolekcji składni elementów właściwości, procesor XAML musi identyfikować typy, które są typami kolekcji. Jeśli element ma właściwość zawartości XAML, a typ właściwości zawartości XAML jest kolekcją, niejawny typ kolekcji nie musi być określony w znaczniku jako element obiektu, a właściwość zawartości XAML nie musi być określona jako element właściwości. W związku z tym model zawartości widocznej w znacznikach może teraz mieć przypisany więcej niż jeden element podrzędny jako zawartość. Poniżej przedstawiono składnię zawartości dla klasy Panel pochodnej. Wszystkie Panel klasy pochodne ustanowią właściwość zawartości XAML na wartość Children, co wymaga wartości typu UIElementCollection.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<StackPanel>
<Button>Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
</StackPanel>
</Page>
Należy pamiętać, że w znacznikach Children nie jest wymagany ani element UIElementCollection właściwości ani element dla elementu . Jest to funkcja projektowania języka XAML, dzięki czemu cyklicznie zawarte elementy definiujące interfejs użytkownika są bardziej intuicyjnie reprezentowane jako drzewo zagnieżdżonych elementów z bezpośrednimi relacjami elementów nadrzędny-podrzędny bez interwencji tagów elementów właściwości ani obiektów kolekcji. W rzeczywistości nie UIElementCollection można jawnie określić w znacznikach jako elementu obiektu, zgodnie z projektem. Ponieważ jej jedynym przeznaczeniem jest kolekcja niejawna, UIElementCollection nie uwidacznia publicznego konstruktora bez parametrów i dlatego nie można utworzyć wystąpienia jako elementu obiektu.
Mieszanie elementów właściwości i elementów obiektu w obiekcie z właściwością zawartości
Specyfikacja XAML deklaruje, że procesor XAML może wymuszać te elementy obiektu, które są używane do wypełniania właściwości zawartości XAML w elemencie obiektu, muszą być ciągłe i nie mogą być mieszane. To ograniczenie przed mieszaniem elementów właściwości i zawartości jest wymuszane przez procesory XAML WPF.
Element obiektu podrzędnego może być pierwszym bezpośrednim znacznikiem w elemencie obiektu. Następnie możesz wprowadzić elementy właściwości. Możesz też określić co najmniej jeden element właściwości, a następnie zawartość, a następnie więcej elementów właściwości. Jednak gdy element właściwości następuje po zawartości, nie można wprowadzić dalszej zawartości, można dodawać tylko elementy właściwości.
To wymaganie dotyczące kolejności elementów zawartości/właściwości nie ma zastosowania do tekstu wewnętrznego używanego jako zawartość. Jednak nadal dobrym stylem znaczników jest zachowanie ciągłego tekstu wewnętrznego, ponieważ znaczne białe znaki będą trudne do wizualnego wykrycia w znacznikach, jeśli elementy właściwości są przeplatone tekstem wewnętrznym.
Przestrzeń nazw XAML
W żadnym z powyższych przykładów składni nie określono przestrzeni nazw XAML innej niż domyślna przestrzeń nazw XAML. W typowych aplikacjach WPF domyślną przestrzenią nazw XAML jest przestrzeń nazw WPF. Można określić przestrzenie nazw XAML inne niż domyślna przestrzeń nazw XAML i nadal używać podobnej składni. Jednak w każdym miejscu, w którym klasa nosi nazwę, która nie jest dostępna w domyślnej przestrzeni nazw XAML, ta nazwa klasy musi być poprzedzona prefiksem przestrzeni nazw XAML zamapowany na odpowiednią przestrzeń nazw CLR. Na przykład <custom:Example/>Example to składnia elementu obiektu służąca do wystąpienia wystąpienia klasy, w której przestrzeń nazw CLR zawierająca klasę (i prawdopodobnie informacje o zestawie zewnętrznym, które zawierają typy zapasowe) custom została wcześniej zamapowana na prefiks.
Aby uzyskać więcej informacji na temat przestrzeni nazw XAML, zobacz Obszary nazw XAML i Mapowanie przestrzeni nazw dla WPF XAML.
Rozszerzenia struktury znaczników
XAML definiuje jednostkę programowania rozszerzenia znaczników, która umożliwia ucieczkę od normalnej obsługi procesora XAML wartości atrybutów ciągu lub elementów obiektu i odraża przetwarzanie do klasy zapasowej. Znak, który identyfikuje rozszerzenie znaczników procesora XAML w przypadku używania składni atrybutów, to otwierający nawias klamrowy ({), po którym następuje dowolny znak inny niż zamykający nawias klamrowy (}). Pierwszy ciąg po otwierającym nawiasie klamrowym musi odwoływać się do klasy, która zapewnia zachowanie określonego rozszerzenia, gdzie odwołanie może pominąć podciąg "Extension", jeśli ten podciąg jest częścią nazwy klasy true. Następnie może pojawić się jedna spacja, a następnie każdy kolejny znak jest używany jako dane wejściowe przez implementację rozszerzenia aż do momentu napotkania zamykającego nawiasu klamrowego.
Implementacja języka XAML platformy MarkupExtension .NET używa klasy abstrakcyjnej jako podstawy dla wszystkich rozszerzeń znaczników obsługiwanych przez WPF, a także innych platform lub technologii. Rozszerzenia znaczników implementowane specjalnie przez WPF są często przeznaczone do zapewnienia środków do odwołania się do innych istniejących obiektów lub do odroczonych odwołań do obiektów, które będą oceniane w czasie działania. Na przykład proste powiązanie danych WPF {Binding} jest realizowane przez określenie rozszerzenia znaczników w miejsce wartości, która normalnie byłaby dzielona na określoną właściwość. Wiele rozszerzeń znaczników WPF umożliwia składnię atrybutów dla właściwości, w przypadku których składnia atrybutów nie byłaby w przeciwnym razie możliwa. Na przykład obiekt jest Style stosunkowo złożonym typem, który zawiera zagnieżdżony szereg obiektów i właściwości. Style w WPF są zwykle definiowane jako zasób w , a ResourceDictionarynastępnie przywołyowane za pośrednictwem jednego z dwóch rozszerzeń znaczników WPF, które żądają zasobu. Rozszerzenie znaczników nie Style ocenia wartości właściwości wyszukiwania zasobów i umożliwia podanie wartości właściwości, Stylebiorąc typ , w składni atrybutu, jak w poniższym przykładzie:
<Button Style="{StaticResource MyStyle}">My button</Button>
W tym StaticResource miejscu identyfikuje klasę StaticResourceExtension dostarczającą implementację rozszerzenia znaczników. Następny ciąg jest MyStyle używany jako dane wejściowe StaticResourceExtension dla konstruktora nie domyślnego, gdzie parametr w postaci pozytywu z ciągu rozszerzenia deklaruje żądany .ResourceKey MyStyle Oczekuje się, że będzie to wartość x:Key zdefiniowanej Style jako zasób. Rozszerzenie znaczników StaticResourceStyle żąda, aby zasób był używany do zapewnienia wartości właściwości za pośrednictwem statycznej logiki wyszukiwania zasobów w czasie ładowania.
Aby uzyskać więcej informacji na temat rozszerzeń znaczników, zobacz Rozszerzenia znaczników i WPF XAML. Aby uzyskać odwołanie do rozszerzeń znaczników i innych funkcji programowania XAML włączonych w ogólnej implementacji języka XAML na platformie .NET, zobacz Przestrzeń nazw XAML (x:) Funkcje językowe. Aby uzyskać informacje na temat rozszerzeń znaczników specyficznych dla WPF, zobacz Rozszerzenia WPF XAML.
Właściwości dołączone
Dołączone właściwości to pojęcie programistyczne wprowadzone w języku XAML, w którym właściwości mogą być własnością określonego typu i przez nie definiowane, ale ustawiane jako atrybuty lub elementy właściwości w dowolnym elemencie. Podstawowym scenariuszem, w którym są dołączone właściwości, jest umożliwienie elementom podrzędnym w strukturze znaczników zgłaszania informacji do elementu nadrzędnego bez konieczności rozbudowanego modelu obiektów udostępnionych we wszystkich elementach. Z drugiej strony dołączone właściwości mogą być używane przez elementy nadrzędne do zgłaszania informacji do elementów nadrzędnych. Aby uzyskać więcej informacji na temat przeznaczenia dołączonych właściwości i sposobu tworzenia własnych dołączonych właściwości, zobacz Attached Properties Overview (Omówienie dołączonych właściwości).
Dołączone właściwości używają składni, która w sposób powierzchnny przypomina składnię elementu właściwości, w tym że należy również określić element typeName. kombinacja propertyName . Istnieją dwie ważne różnice:
Można użyć typeName. Kombinacja propertyName nawet podczas ustawiania dołączonej właściwości za pomocą składni atrybutu. Dołączone właściwości to jedyny przypadek, w którym kwalifikowanie nazwy właściwości jest wymagane w składni atrybutów.
Można również użyć składni elementu właściwości dla dołączonych właściwości. Jednak w przypadku typowej składni elementu właściwości typeName jest elementem obiektu, który zawiera element właściwości. Jeśli odwołujesz się do dołączonej właściwości, typeName jest klasą, która definiuje dołączona właściwość, a nie zawierający element obiektu.
Zdarzenia dołączone
Zdarzenia dołączone to kolejna koncepcja programowania wprowadzona w języku XAML, w której zdarzenia mogą być definiowane przez określony typ, ale procedury obsługi mogą być dołączane do dowolnego elementu obiektu. W implementacji WOF często typ, który definiuje dołączone zdarzenie, jest typem statycznym definiującym usługę, a czasami te dołączone zdarzenia są uwidocznione przez alias zdarzenia trasowane w typach, które uwidoczniają usługę. Procedury obsługi dla dołączonych zdarzeń są określane za pomocą składni atrybutów. Podobnie jak w przypadku zdarzeń dołączonych, składnia atrybutów jest rozwinięta dla dołączonych zdarzeń, aby zezwolić na typeName. użycie eventName , gdzie typeName jest AddRemove klasą, która zapewnia dostęp do programu obsługi zdarzeń i dla dołączonej infrastruktury zdarzeń, a eventName jest nazwą zdarzenia.
Anatomia elementu głównego XAML
W poniższej tabeli przedstawiono typowy element główny XAML z podziałem, pokazujący określone atrybuty elementu głównego:
| Atrybut | Opis |
|---|---|
<Page |
Otwieranie elementu obiektu elementu głównego |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
Domyślna przestrzeń nazw XAML (WPF) |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
Przestrzeń nazw XAML języka XAML |
x:Class="ExampleNamespace.ExampleCode" |
Deklaracja klasy częściowej, która łączy znacznik z dowolnym kodem zdefiniowanym dla klasy częściowej |
> |
Koniec elementu obiektu dla katalogu głównego. Obiekt nie jest jeszcze zamknięty, ponieważ element zawiera elementy podrzędne |
Opcjonalne i nierecomedywne użycie języka XAML
W poniższych sekcjach opisano użycie języka XAML, które jest technicznie obsługiwane przez procesory XAML, ale które wywołują szczegółowość lub inne problemy z wyglądem, które zakłócają czytelność plików XAML podczas tworzenia aplikacji zawierających źródła XAML.
Użycie opcjonalnego elementu właściwości
Opcjonalne użycie elementów właściwości obejmuje jawne zapisywanie właściwości zawartości elementu, które procesor XAML uznaje za niejawne. Na przykład podczas deklarowania zawartości obiektu można jawnie zadeklarować kolekcję jako tag MenuItem<Menu.Items>elementu właściwości i umieścić je w obiekcie , zamiast <Menu.Items> korzystać z niejawnego zachowania procesora XAMLMenu, zgodnie z którym wszystkie elementy podrzędne obiektu muszą być elementami MenuItemItems i są umieszczane w kolekcji.MenuItemsMenu Czasami opcjonalne użycie może pomóc w wizualnej wyjaśnieniu struktury obiektu reprezentowanej w znacznikach. Czasami jawne użycie elementu właściwości może uniknąć na znaczników, które są technicznie funkcjonalne, ale wizualnie mylące, na przykład zagnieżdżone rozszerzenia znaczników w wartości atrybutu.
Full typeName.memberName Qualified Attributes
TypeName. Formularz memberName atrybutu w rzeczywistości działa bardziej uniwersalnie niż tylko przypadek zdarzenia trasowane. Jednak w innych sytuacjach ten formularz jest zbędny i należy go unikać, jeśli tylko ze względu na styl narzutu i czytelność. W poniższym przykładzie każde z trzech odwołań do atrybutu Background jest całkowicie równoważne:
<Button Background="Blue">Background</Button>
<Button Button.Background="Blue">Button.Background</Button>
<Button Control.Background="Blue">Control.Background</Button>
Button.Background Działa, ponieważ kwalifikowane wyszukiwania Button dla tej właściwości na jest pomyślny (Background został odziedziczony z Control) Button i jest klasą elementu obiektu lub klasy bazowej. Control.Background Działa, ponieważ klasa Control faktycznie definiuje klasę Background i Control jest klasą Button bazową.
Jednak poniższy typNazwa. Przykład formularza memberName nie działa i dlatego jest wyświetlany jako komentarz:
<!--<Button Label.Background="Blue">Does not work</Button> -->
Labeljest inną klasą pochodną Controlklasy , a Label jeśli określono w Label.Background elemencie obiektu, to użycie działałoby. Jednak ze względu na Label to, że nie jest klasą ani klasą bazową Buttonklasy , określone zachowanie procesora XAML Label.Background ma być następnie przetwarzane jako właściwość dołączona. Label.Background nie jest dostępną dołączona właściwością, a to użycie kończy się niepowodzeniem.
baseTypeName.memberName, elementy właściwości
W sposób analogiczny do sposobu typeName. Formularz memberName działa w przypadku składni atrybutów , baseTypeName. Składnia memberName działa w przypadku składni elementu właściwości. Na przykład działa następująca składnia:
<Button>Control.Background PE
<Control.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="LimeGreen" Offset="1.0" />
</LinearGradientBrush>
</Control.Background>
</Button>
Tutaj element właściwości został podany tak, Control.Background jakby element właściwości znajdował się w elemencie Button.
Ale podobnie jak typeName. Formularz memberName dla atrybutów , baseTypeName. Parametr memberName ma słaby styl w znacznikach i należy go unikać.