Rozszerzenia struktury znaczników XAML
Rozszerzenia znaczników XAML interfejsu użytkownika aplikacji wieloplatformowej platformy .NET (.NET MAUI) umożliwiają ustawianie właściwości na obiekty lub wartości, do których odwołuje się pośrednio z innych źródeł. Rozszerzenia znaczników XAML są szczególnie ważne w przypadku udostępniania obiektów i odwoływania się do stałych używanych w całej aplikacji, ale znajdują swoje największe narzędzie w powiązaniach danych.
Zazwyczaj używasz języka XAML do ustawiania właściwości obiektu na jawne wartości, takie jak ciąg, liczba, składowa wyliczenia lub ciąg, który jest konwertowany na wartość w tle. Czasami jednak właściwości muszą odwoływać się do wartości zdefiniowanych w innym miejscu lub które mogą wymagać nieco przetwarzania przez kod w czasie wykonywania. W tych celach dostępne są rozszerzenia znaczników XAML.
Rozszerzenia znaczników XAML są tak nazwane, ponieważ są one wspierane przez kod w klasach implementujących IMarkupExtension. Istnieje również możliwość zapisania własnych niestandardowych rozszerzeń znaczników.
W wielu przypadkach rozszerzenia znaczników XAML są natychmiast rozpoznawalne w plikach XAML, ponieważ są one wyświetlane jako wartości atrybutów rozdzielane nawiasami klamrowymi, { i }, ale czasami rozszerzenia znaczników również pojawiają się w znacznikach jako konwencjonalne elementy.
Ważne
Rozszerzenia znaczników mogą mieć właściwości, ale nie są ustawione tak jak atrybuty XML. W rozszerzeniu znaczników ustawienia właściwości są oddzielone przecinkami, a żadne znaki cudzysłowu nie są wyświetlane w nawiasach klamrowych.
Współdzielone zasoby
Niektóre strony XAML zawierają kilka widoków z właściwościami ustawionymi na te same wartości. Na przykład wiele ustawień właściwości dla tych Button obiektów jest takich samych:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.SharedResourcesPage"
Title="Shared Resources Page">
<StackLayout>
<Button Text="Do this!"
HorizontalOptions="Center"
VerticalOptions="Center"
BorderWidth="3"
Rotation="-15"
TextColor="Red"
FontSize="24" />
<Button Text="Do that!"
HorizontalOptions="Center"
VerticalOptions="Center"
BorderWidth="3"
Rotation="-15"
TextColor="Red"
FontSize="24" />
<Button Text="Do the other thing!"
HorizontalOptions="Center"
VerticalOptions="Center"
BorderWidth="3"
Rotation="-15"
TextColor="Red"
FontSize="24" />
</StackLayout>
</ContentPage>
Jeśli należy zmienić jedną z tych właściwości, możesz wolisz wprowadzić zmianę tylko raz, a nie trzy razy. Gdyby był to kod, prawdopodobnie będziesz używać stałych i statycznych obiektów tylko do odczytu, aby zachować takie wartości spójne i łatwe do zmodyfikowania.
W języku XAML jednym z popularnych rozwiązań jest przechowywanie takich wartości lub obiektów w słowniku zasobów. Klasa VisualElement definiuje właściwość o nazwie Resources
typu ResourceDictionary, która jest słownikiem z kluczami typu string
i wartości typu object
. Można umieścić obiekty w tym słowniku, a następnie odwołać się do nich z znaczników, wszystkie w języku XAML.
Aby użyć słownika zasobów na stronie, dołącz parę tagów Resources
właściwości-element w górnej części strony i dodaj zasoby w tych tagach. Obiekty i wartości różnych typów można dodać do słownika zasobów. Te typy muszą być tworzone wystąpienia. Nie mogą być na przykład klas abstrakcyjnych. Te typy muszą również mieć publiczny konstruktor bez parametrów. Każdy element wymaga klucza słownika określonego za pomocą atrybutu x:Key
:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.SharedResourcesPage"
Title="Shared Resources Page">
<ContentPage.Resources>
<LayoutOptions x:Key="horzOptions"
Alignment="Center" />
<LayoutOptions x:Key="vertOptions"
Alignment="Center" />
</ContentPage.Resources>
...
</ContentPage>
W tym przykładzie dwa zasoby są wartościami typu LayoutOptions
struktury , a każdy z nich ma unikatowy klucz i jedną lub dwie właściwości ustawione. W kodzie i narzucie jest znacznie częściej używane statyczne pola LayoutOptions
, ale w tym miejscu bardziej wygodne jest ustawienie właściwości.
Uwaga
Opcjonalne ResourceDictionary tagi można dołączać jako element podrzędny Resources
tagów.
Zasoby mogą być następnie używane przez Button obiekty przy użyciu StaticResource
rozszerzenia znaczników XAML w celu ustawienia ich HorizontalOptions
właściwości i VerticalOptions
:
<Button Text="Do this!"
HorizontalOptions="{StaticResource horzOptions}"
VerticalOptions="{StaticResource vertOptions}"
BorderWidth="3"
Rotation="-15"
TextColor="Red"
FontSize="24" />
StaticResource
Rozszerzenie znaczników jest zawsze rozdzielane nawiasami klamrowymi i zawiera klucz słownika. Nazwa StaticResource
odróżnia ją od DynamicResource
elementu , który obsługuje również program .NET MAUI. DynamicResource
jest przeznaczony dla kluczy słownika skojarzonych z wartościami, które mogą ulec zmianie w czasie wykonywania, podczas gdy StaticResource
są tworzone elementy ze słownika tylko raz. Za każdym razem, gdy analizator XAML napotka StaticResource
rozszerzenie znaczników, wyszukuje drzewo wizualne i używa pierwszego ResourceDictionary napotkanego klucza zawierającego ten klucz.
Należy przechowywać dublety w słowniku BorderWidth
dla właściwości , Rotation
i FontSize
. Język XAML wygodnie definiuje tagi dla typowych typów danych, takich jak x:Double
i x:Int32
:
<ContentPage.Resources>
<LayoutOptions x:Key="horzOptions"
Alignment="Center" />
<LayoutOptions x:Key="vertOptions"
Alignment="Center" />
<x:Double x:Key="borderWidth">3</x:Double>
<x:Double x:Key="rotationAngle">-15</x:Double>
<x:Double x:Key="fontSize">24</x:Double>
</ContentPage.Resources>
Te dodatkowe trzy zasoby można odwoływać się w taki sam sposób, jak w przypadku LayoutOptions
wartości:
<Button Text="Do this!"
HorizontalOptions="{StaticResource horzOptions}"
VerticalOptions="{StaticResource vertOptions}"
BorderWidth="{StaticResource borderWidth}"
Rotation="{StaticResource rotationAngle}"
TextColor="Red"
FontSize="{StaticResource fontSize}" />
W przypadku zasobów typu Colormożna użyć tych samych reprezentacji ciągów, które są używane podczas bezpośredniego przypisywania atrybutów tych typów. Konwertery typów zawarte w interfejsie MAUI platformy .NET są wywoływane podczas tworzenia zasobu. Można również użyć OnPlatform
klasy w słowniku zasobów, aby zdefiniować różne wartości dla platform. W poniższym przykładzie użyto tej klasy do ustawiania różnych kolorów tekstu:
<OnPlatform x:Key="textColor"
x:TypeArguments="Color">
<On Platform="iOS" Value="Red" />
<On Platform="Android" Value="Aqua" />
</OnPlatform>
Zasób OnPlatform
pobiera x:Key
atrybut, ponieważ jest to obiekt w słowniku i x:TypeArguments
atrybut, ponieważ jest to klasa ogólna. Atrybuty iOS
i są Android
konwertowane na Color wartości podczas inicjowania obiektu.
W poniższym przykładzie przedstawiono trzy przyciski, które uzyskują dostęp do sześciu wartości udostępnionych:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.SharedResourcesPage"
Title="Shared Resources Page">
<ContentPage.Resources>
<LayoutOptions x:Key="horzOptions"
Alignment="Center" />
<LayoutOptions x:Key="vertOptions"
Alignment="Center" />
<x:Double x:Key="borderWidth">3</x:Double>
<x:Double x:Key="rotationAngle">-15</x:Double>
<x:Double x:Key="fontSize">24</x:Double>
<OnPlatform x:Key="textColor"
x:TypeArguments="Color">
<On Platform="iOS" Value="Red" />
<On Platform="Android" Value="Aqua" />
<On Platform="WinUI" Value="#80FF80" />
</OnPlatform>
</ContentPage.Resources>
<StackLayout>
<Button Text="Do this!"
HorizontalOptions="{StaticResource horzOptions}"
VerticalOptions="{StaticResource vertOptions}"
BorderWidth="{StaticResource borderWidth}"
Rotation="{StaticResource rotationAngle}"
TextColor="{StaticResource textColor}"
FontSize="{StaticResource fontSize}" />
<Button Text="Do that!"
HorizontalOptions="{StaticResource horzOptions}"
VerticalOptions="{StaticResource vertOptions}"
BorderWidth="{StaticResource borderWidth}"
Rotation="{StaticResource rotationAngle}"
TextColor="{StaticResource textColor}"
FontSize="{StaticResource fontSize}" />
<Button Text="Do the other thing!"
HorizontalOptions="{StaticResource horzOptions}"
VerticalOptions="{StaticResource vertOptions}"
BorderWidth="{StaticResource borderWidth}"
Rotation="{StaticResource rotationAngle}"
TextColor="{StaticResource textColor}"
FontSize="{StaticResource fontSize}" />
</StackLayout>
</ContentPage>
Poniższy zrzut ekranu weryfikuje spójny styl:
Chociaż często definiuje Resources
się kolekcję w górnej części strony, kolekcje mogą znajdować Resources
się na innych elementach na stronie. Na przykład w poniższym przykładzie przedstawiono zasoby dodane do elementu StackLayout:
<StackLayout>
<StackLayout.Resources>
<Color x:Key="textColor">Blue</Color>
</StackLayout.Resources>
...
</StackLayout>
Jednym z najpopularniejszych typów obiektów przechowywanych w słownikach zasobów jest program .NET MAUI Style, który definiuje kolekcję ustawień właściwości. Aby uzyskać więcej informacji na temat stylów, zobacz Style apps using XAML (Aplikacje stylów przy użyciu języka XAML).
Uwaga
Celem słownika zasobów jest udostępnianie obiektów. W związku z tym nie ma sensu umieszczać kontrolek, takich jak Label lub Button w słowniku zasobów. Nie można udostępnić elementów wizualnych, ponieważ to samo wystąpienie nie może być wyświetlane dwa razy na stronie.
x:Static — Rozszerzenie znaczników
Oprócz StaticResource
rozszerzenia znaczników istnieje również x:Static
rozszerzenie znaczników. Jednak podczas zwracania StaticResource
obiektu ze słownika zasobów uzyskujex:Static
dostęp do publicznego pola statycznego, właściwości statycznej publicznej, pola stałej publicznej lub elementu członkowskiego wyliczenia.
Uwaga
StaticResource
Rozszerzenie znaczników jest obsługiwane przez implementacje XAML, które definiują słownik zasobów, podczas gdy x:Static
jest wewnętrzną częścią XAML, jak x
ujawnia prefiks.
W poniższym przykładzie pokazano, jak x:Static
jawnie odwoływać się do pól statycznych i elementów członkowskich wyliczenia:
<Label Text="Hello, XAML!"
VerticalOptions="{x:Static LayoutOptions.Start}"
HorizontalTextAlignment="{x:Static TextAlignment.Center}"
TextColor="{x:Static Colors.Aqua}" />
Głównym zastosowaniem x:Static
rozszerzenia znaczników jest odwoływanie się do pól statycznych lub właściwości z własnego kodu. Oto na przykład AppConstants
klasa zawierająca niektóre pola statyczne, których można użyć na wielu stronach w całej aplikacji:
namespace XamlSamples
{
static class AppConstants
{
public static readonly Color BackgroundColor = Colors.Aqua;
public static readonly Color ForegroundColor = Colors.Brown;
}
}
Aby odwołać się do pól statycznych tej klasy w pliku XAML, należy użyć deklaracji przestrzeni nazw XML, aby wskazać, gdzie znajduje się ten plik. Każda dodatkowa deklaracja przestrzeni nazw XML definiuje nowy prefiks. Aby uzyskać dostęp do klas lokalnych w przestrzeni nazw aplikacji głównej, takiej jak AppConstants
, można użyć prefiksu local
. Deklaracja przestrzeni nazw musi wskazywać nazwę przestrzeni nazw CLR (środowisko uruchomieniowe języka wspólnego), znaną również jako nazwa przestrzeni nazw platformy .NET, która jest nazwą wyświetlaną w definicji języka C# namespace
lub w using
dyrektywie:
xmlns:local="clr-namespace:XamlSamples"
Można również zdefiniować deklaracje przestrzeni nazw XML dla przestrzeni nazw platformy .NET. Oto na przykład sys
prefiks dla standardowej przestrzeni nazw platformy .NET System
, która znajduje się w netstandard
zestawie. Ponieważ jest to inny zestaw, należy również określić nazwę zestawu, w tym przypadku netstandard
:
xmlns:sys="clr-namespace:System;assembly=netstandard"
Uwaga
Po słowie kluczowym clr-namespace
następuje dwukropek, a następnie nazwa przestrzeni nazw platformy .NET, po której następuje średnik, słowo kluczowe assembly
, znak równości i nazwa zestawu.
Pola statyczne można następnie używać po zadeklarowaniu przestrzeni nazw XML:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples"
xmlns:sys="clr-namespace:System;assembly=netstandard"
x:Class="XamlSamples.StaticConstantsPage"
Title="Static Constants Page"
Padding="5,25,5,0">
<StackLayout>
<Label Text="Hello, XAML!"
TextColor="{x:Static local:AppConstants.BackgroundColor}"
BackgroundColor="{x:Static local:AppConstants.ForegroundColor}"
FontAttributes="Bold"
FontSize="30"
HorizontalOptions="Center" />
<BoxView WidthRequest="{x:Static sys:Math.PI}"
HeightRequest="{x:Static sys:Math.E}"
Color="{x:Static local:AppConstants.ForegroundColor}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Scale="100" />
</StackLayout>
</ContentPage>
W tym przykładzie BoxView wymiary są ustawione na Math.PI
i Math.E
, ale skalowane według współczynnika 100:
Inne rozszerzenia znaczników
Kilka rozszerzeń znaczników jest wewnętrznych dla języka XAML i obsługiwanych w języku XAML .NET MAUI. Niektóre z nich nie są używane bardzo często, ale są niezbędne, gdy ich potrzebujesz:
- Jeśli właściwość ma wartość inną niż
null
domyślna, ale chcesz ją ustawić nanull
, ustaw ją na{x:Null}
rozszerzenie znaczników. - Jeśli właściwość jest typu
Type
, można przypisać ją doType
obiektu przy użyciu rozszerzenia{x:Type someClass}
znaczników . - Tablice w języku XAML można definiować przy użyciu
x:Array
rozszerzenia znaczników. To rozszerzenie znaczników ma wymagany atrybut o nazwieType
, który wskazuje typ elementów w tablicy.
Aby uzyskać więcej informacji na temat rozszerzeń znaczników XAML, zobacz Korzystanie z rozszerzeń znaczników XAML.
Następne kroki
Powiązania danych programu .NET MAUI umożliwiają połączenie właściwości dwóch obiektów, dzięki czemu zmiana w jednym powoduje zmianę w drugiej.