Korzystanie z rozszerzeń znaczników XAML
Rozszerzenia znaczników XAML (.NET MAUI) wieloplatformowych interfejsów użytkownika aplikacji platformy .NET pomagają zwiększyć moc i elastyczność języka XAML, umożliwiając ustawianie atrybutów elementów z różnych źródeł.
Na przykład zazwyczaj ustawiasz właściwość Color
dla BoxView w następujący sposób:
<BoxView Color="Blue" />
Jednak zamiast tego można ustawić atrybut Color
z wartości przechowywanej w słowniku zasobów lub z wartości statycznej klasy, która została utworzona, lub na podstawie właściwości typu Color innego elementu na stronie lub skonstruowanej z oddzielnych wartości odcieni, nasycenia i jasności. Wszystkie te opcje są możliwe przy użyciu rozszerzeń znaczników XAML.
Rozszerzenie znacznika to alternatywny sposób wyrażania atrybutu elementu. Rozszerzenia znaczników XAML technologii .NET MAUI są zwykle możliwe do zidentyfikowania przez wartość atrybutu, która jest ujęta w klamry:
<BoxView Color="{StaticResource themeColor}" />
Każda wartość atrybutu w nawiasach klamrowych jest zawsze rozszerzeniem znaczników XAML. Można jednak odwoływać się do rozszerzeń składni XAML bez użycia nawiasów klamrowych.
Notatka
Kilka rozszerzeń znaczników XAML jest częścią specyfikacji XAML 2009. Są one wyświetlane w plikach XAML ze zwyczajowym prefiksem x
przestrzeni nazw i są często określane z tym prefiksem.
Oprócz rozszerzeń znaczników omówionych w tym artykule następujące rozszerzenia znaczników są zawarte w programie .NET MAUI i omówione w innych artykułach:
-
AppThemeBinding
— określa zasób, który ma być używany na podstawie bieżącego motywu systemu. Aby uzyskać więcej informacji, zobacz AppThemeBinding markup extension. -
Binding
— ustanawia połączenie między właściwościami dwóch obiektów. Aby uzyskać więcej informacji, zobacz Powiązanie danych. -
DynamicResource
— reaguje na zmiany w obiektach w słowniku zasobów. Aby uzyskać więcej informacji, zobacz Style dynamiczne. -
FontImage
— wyświetla ikonę czcionki w dowolnym widoku, który może wyświetlać ImageSource. Aby uzyskać więcej informacji, zobacz Załaduj ikonę czcionki. -
OnIdiom
— dostosowuje wygląd interfejsu użytkownika na podstawie idiomu urządzenia, na którym działa aplikacja. Aby uzyskać więcej informacji, zobacz Dostosowywanie wyglądu interfejsu użytkownika na podstawie typu urządzenia. -
OnPlatform
— dostosowuje wygląd interfejsu użytkownika dla poszczególnych platform. Aby uzyskać więcej informacji, zobacz Dostosowywanie wyglądu interfejsu użytkownika na podstawie platformy. -
RelativeSource
— ustawia źródło powiązania względem pozycji elementu docelowego powiązania. Aby uzyskać więcej informacji, zobacz powiązania względne. -
StaticResource
— odwołuje się do obiektów ze słownika zasobów. Aby uzyskać więcej informacji, zobacz Słowniki zasobów. -
TemplateBinding
— wykonuje powiązanie danych z szablonu kontrolki. Aby uzyskać więcej informacji, zobacz Szablony kontrolek.
x:Statyczne rozszerzenie znaczników
Rozszerzenie znaczników x:Static
jest obsługiwane przez klasę StaticExtension. Klasa ma jedną właściwość o nazwie Member
typu string
, którą ustawiasz na nazwę stałej publicznej, właściwości statycznej, pola statycznego lub składowej wyliczenia.
Jednym ze sposobów użycia x:Static
jest najpierw zdefiniowanie klasy z niektórymi stałymi lub zmiennymi statycznymi, takimi jak ta klasa AppConstants
:
static class AppConstants
{
public static double NormalFontSize = 18;
}
Poniższy kod XAML przedstawia najbardziej rozwlekłe podejście do tworzenia wystąpienia klasy StaticExtension między znacznikami elementu właściwości Label.FontSize
.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sys="clr-namespace:System;assembly=netstandard"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.StaticDemoPage"
Title="x:Static Demo">
<StackLayout Margin="10, 0">
<Label Text="Label No. 1">
<Label.FontSize>
<x:StaticExtension Member="local:AppConstants.NormalFontSize" />
</Label.FontSize>
</Label>
···
</StackLayout>
</ContentPage>
Analizator XAML umożliwia również skrót klasy StaticExtension jako x:Static
:
<Label Text="Label No. 2">
<Label.FontSize>
<x:Static Member="local:AppConstants.NormalFontSize" />
</Label.FontSize>
</Label>
Tę składnię można jeszcze bardziej uprościć, umieszczając klasę StaticExtension i ustawienie członka w nawiasach klamrowych. Wynikowe wyrażenie jest ustawiane bezpośrednio na atrybut FontSize
:
<Label Text="Label No. 3"
FontSize="{x:StaticExtension Member=local:AppConstants.NormalFontSize}" />
W tym przykładzie w nawiasach klamrowych nie ma żadnych znaków cudzysłowu. Właściwość Member
obiektu StaticExtension nie jest już atrybutem XML. Zamiast tego jest częścią wyrażenia rozszerzenia znaczników.
Tak jak można skrócić x:StaticExtension
do x:Static
, gdy używasz go jako elementu obiektu, możesz również skrócić go w wyrażeniu w nawiasach klamrowych:
<Label Text="Label No. 4"
FontSize="{x:Static Member=local:AppConstants.NormalFontSize}" />
Klasa StaticExtension ma atrybut ContentProperty
odwołujące się do właściwości Member
, która oznacza tę właściwość jako domyślną właściwość zawartości klasy. W przypadku rozszerzeń znaczników XAML wyrażonych za pomocą nawiasów klamrowych można wyeliminować część wyrażenia Member=
:
<Label Text="Label No. 5"
FontSize="{x:Static local:AppConstants.NormalFontSize}" />
Jest to najbardziej typowa forma rozszerzenia znaczników x:Static
.
Główny tag przykładu XAML zawiera również deklarację przestrzeni nazw XML dla przestrzeni nazw platformy .NET System
. Dzięki temu można ustawić rozmiar czcionki Label na pole statyczne Math.PI
. Powoduje to raczej mały tekst, więc właściwość Scale
jest ustawiona na Math.E
:
<Label Text="π × E sized text"
FontSize="{x:Static sys:Math.PI}"
Scale="{x:Static sys:Math.E}"
HorizontalOptions="Center" />
Poniższy zrzut ekranu przedstawia dane wyjściowe XAML:
x:Reference markup extension (Rozszerzenie znaczników x:Reference)
Rozszerzenie znaczników x:Reference
jest obsługiwane przez klasę ReferenceExtension. Klasa ma jedną właściwość o nazwie Name
typu string
, którą ustawiasz na nazwę elementu na stronie, który otrzymał nazwę z x:Name
. Ta właściwość Name
jest właściwością treści ReferenceExtension, dlatego Name=
nie jest wymagana, gdy x:Reference
pojawia się w nawiasach klamrowych. Rozszerzenie znaczników x:Reference
jest używane wyłącznie z powiązaniami danych. Aby uzyskać więcej informacji na temat powiązań danych, zobacz Powiązanie danych.
Poniższy przykład XAML przedstawia dwa zastosowania x:Reference
z powiązaniami danych, pierwszy, w którym jest używany do ustawiania właściwości Source
obiektu Binding
, a drugi, w którym jest używana do ustawiania właściwości BindingContext
dla dwóch powiązań danych:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.ReferenceDemoPage"
x:Name="page"
Title="x:Reference Demo">
<StackLayout Margin="10, 0">
<Label x:DataType="ContentPage"
Text="{Binding Source={x:Reference page},
StringFormat='The type of this page is {0}'}"
FontSize="18"
VerticalOptions="Center"
HorizontalTextAlignment="Center" />
<Slider x:Name="slider"
Maximum="360"
VerticalOptions="Center" />
<Label x:DataType="Slider"
BindingContext="{x:Reference slider}"
Text="{Binding Value, StringFormat='{0:F0}° rotation'}"
Rotation="{Binding Value}"
FontSize="24"
HorizontalOptions="Center"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
W tym przykładzie oba wyrażenia x:Reference
stosują skróconą wersję nazwy klasy ReferenceExtension i eliminują część wyrażenia Name=
. W pierwszym przykładzie rozszerzenie znaczników x:Reference
jest osadzone w rozszerzeniu znaczników Binding
, a właściwości Source
i StringFormat
są oddzielone przecinkami.
Poniższy zrzut ekranu przedstawia dane wyjściowe XAML:
x:Type, rozszerzenie znaczników
Rozszerzenie znaczników x:Type
jest odpowiednikiem w XAML słowa kluczowego typeof
w języku C#. Jest obsługiwana przez klasę TypeExtension, która definiuje właściwość o nazwie TypeName
typu string
, która powinna być ustawiona na nazwę klasy lub struktury. Rozszerzenie znaczników x:Type
zwraca obiekt Type
tej klasy lub struktury.
TypeName
jest właściwością treści TypeExtension, dlatego TypeName=
nie jest wymagany, gdy x:Type
pojawia się z nawiasami klamrowymi.
Rozszerzenie znaczników x:Type
jest często używane z rozszerzeniem znaczników x:Array
. Aby uzyskać więcej informacji, zobacz rozszerzenie znaczników x:Array.
W poniższym przykładzie XAML pokazano użycie rozszerzenia markup x:Type
w celu utworzenia instancji obiektów .NET MAUI i dodania ich do StackLayout. Język XAML składa się z trzech elementów Button, których właściwości Command
są ustawione na Binding
, a właściwości CommandParameter
ustawiono na typy trzech widoków platformy .NET MAUI.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.TypeDemoPage"
Title="x:Type Demo"
x:DataType="local:TypeDemoPage">
<StackLayout x:Name="stackLayout"
Padding="10, 0">
<Button Text="Create a Slider"
HorizontalOptions="Center"
VerticalOptions="Center"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Slider}" />
<Button Text="Create a Stepper"
HorizontalOptions="Center"
VerticalOptions="Center"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Stepper}" />
<Button Text="Create a Switch"
HorizontalOptions="Center"
VerticalOptions="Center"
Command="{Binding CreateCommand}"
CommandParameter="{x:Type Switch}" />
</StackLayout>
</ContentPage>
Plik code-behind definiuje i inicjuje właściwość CreateCommand
:
public partial class TypeDemoPage : ContentPage
{
public ICommand CreateCommand { get; private set; }
public TypeDemoPage()
{
InitializeComponent();
CreateCommand = new Command<Type>((Type viewType) =>
{
View view = (View)Activator.CreateInstance(viewType);
view.VerticalOptions = LayoutOptions.Center;
stackLayout.Add(view);
});
BindingContext = this;
}
}
Po naciśnięciu Button zostanie utworzone nowe wystąpienie argumentu CommandParameter
i dodane do StackLayout. Trzy obiekty Button następnie współdzielą stronę z dynamicznie utworzonymi widokami:
Typy ogólne można określić za pomocą rozszerzenia znaczników x:Type
, określając ograniczenie ogólne jako prefiksowany argument ciągu w nawiasach:
<x:Array Type="{x:Type local:MyType(local:MyObject)}">
...
</x:Array>
Argumenty wielu typów można określić jako prefiksowe argumenty ciągów rozdzielane przecinkami:
<x:Array Type="{x:Type local:MyType(local:MyObject,x:Boolean)}">
...
</x:Array>
Aby uzyskać więcej informacji na temat typów ogólnych w języku XAML, zobacz Generics.
x:Array, rozszerzenie znaczników
Rozszerzenie znacznika x:Array
umożliwia zdefiniowanie tablicy w znaczniku. Jest obsługiwany przez klasę ArrayExtension, która definiuje dwie właściwości:
-
Type
typuType
, co wskazuje na typ elementów w tablicy. Ta właściwość powinna być ustawiona na rozszerzenie znacznikówx:Type
. -
Items
typuIList
, który jest kolekcją samych elementów. Jest to właściwość zawartości ArrayExtension.
Rozszerzenie znacznikowe x:Array
nigdy nie pojawia się w nawiasach klamrowych. Zamiast tego, tagi początkowe i końcowe x:Array
wyznaczają listę elementów.
W poniższym przykładzie XAML pokazano, jak używać x:Array
do dodawania elementów do ListView przez ustawienie właściwości ItemsSource
na tablicę:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.ArrayDemoPage"
Title="x:Array Demo Page">
<ListView Margin="10">
<ListView.ItemsSource>
<x:Array Type="{x:Type Color}">
<Color>Aqua</Color>
<Color>Black</Color>
<Color>Blue</Color>
<Color>Fuchsia</Color>
<Color>Gray</Color>
<Color>Green</Color>
<Color>Lime</Color>
<Color>Maroon</Color>
<Color>Navy</Color>
<Color>Olive</Color>
<Color>Pink</Color>
<Color>Purple</Color>
<Color>Red</Color>
<Color>Silver</Color>
<Color>Teal</Color>
<Color>White</Color>
<Color>Yellow</Color>
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate x:DataType="Color">
<ViewCell>
<BoxView Color="{Binding}"
Margin="3" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
W tym przykładzie ViewCell tworzy prosty BoxView dla każdego wpisu koloru:
Notatka
Podczas definiowania tablic typowych typów, takich jak ciągi lub liczby, użyj tagów prymitywnych języka XAML wymienionych w Pass arguments.
x:Null, rozszerzenie znaczników
Rozszerzenie znaczników x:Null
jest obsługiwane przez klasę NullExtension. Nie ma właściwości i jest po prostu odpowiednikiem XAML słowa kluczowego null
języka C#.
W poniższym przykładzie XAML pokazano, jak używać rozszerzenia znaczników x:Null
:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.NullDemoPage"
Title="x:Null Demo">
<ContentPage.Resources>
<Style TargetType="Label">
<Setter Property="FontSize" Value="48" />
<Setter Property="FontFamily" Value="OpenSansRegular" />
</Style>
</ContentPage.Resources>
<StackLayout Padding="10, 0">
<Label Text="Text 1" />
<Label Text="Text 2" />
<Label Text="Text 3"
FontFamily="{x:Null}" />
<Label Text="Text 4" />
<Label Text="Text 5" />
</StackLayout>
</ContentPage>
W tym przykładzie zdefiniowano niejawną Style dla Label, która zawiera Setter ustawiającą właściwość FontFamily
na określoną czcionkę. Jednak trzeci Label unika używania czcionki zdefiniowanej w stylu niejawnych, ustawiając jej FontFamily
na x:Null
:
Rozszerzenie znacznikowe DataTemplate
Funkcja rozszerzenia znaczników DataTemplate umożliwia konwertowanie typu na DataTemplate. Jest obsługiwana przez klasę DataTemplateExtension, która definiuje właściwość TypeName
typu string
, która jest ustawiona na nazwę typu, który ma zostać przekonwertowany na DataTemplate. Właściwość TypeName
jest właściwością zawartości DataTemplateExtension. W przypadku wyrażeń znaczników XAML zapisanych za pomocą nawiasów klamrowych można wyeliminować fragment wyrażenia TypeName=
.
Notatka
Analizator XAML umożliwia skrót klasy DataTemplateExtension jako DataTemplate.
Typowe użycie tego rozszerzenia znaczników można znaleźć w aplikacji Shell, jak pokazano w poniższym przykładzie.
<ShellContent Title="Monkeys"
Icon="monkey.png"
ContentTemplate="{DataTemplate views:MonkeysPage}" />
W tym przykładzie MonkeysPage
jest konwertowana z ContentPage na DataTemplate, która jest ustawiana jako wartość właściwości ShellContent.ContentTemplate
. Gwarantuje to, że MonkeysPage
jest tworzony tylko podczas nawigacji na stronie, a nie podczas uruchamiania aplikacji.
Aby uzyskać więcej informacji o aplikacjach Shell, zobacz Shell.