Использование расширений разметки XAML

Browse sample. Обзор примера

Расширения разметки XAML для многоплатформенных приложений .NET (.NET MAUI) помогают повысить мощность и гибкость XAML, позволяя задавать атрибуты элементов из различных источников.

Например, обычно вы задаете Color свойство следующего BoxView вида:

<BoxView Color="Blue" />

Однако вместо этого можно задать Color атрибут из значения, хранящегося в словаре ресурсов, или из значения статического свойства класса, созданного вами, или из свойства типа Color другого элемента на странице или из отдельных оттенков, насыщенности и значений светимости. Все эти параметры возможны с помощью расширений разметки XAML.

Расширение разметки отличается от способа выражения атрибута элемента. Расширения разметки XAML для .NET MAUI обычно можно определить по значению атрибута, заключенному в фигурные скобки:

<BoxView Color="{StaticResource themeColor}" />

Любое значение атрибута в фигурных скобках всегда является расширением разметки XAML. Однако расширения разметки XAML также можно ссылаться без использования фигурных скобок.

Примечание.

Несколько расширений разметки XAML являются частью спецификации XAML 2009. Они отображаются в XAML-файлах с префиксом обычного x пространства имен и обычно называются этим префиксом.

Помимо расширений разметки, описанных в этой статье, следующие расширения разметки включены в .NET MAUI и рассматриваются в других статьях:

Расширение разметки x:Static

x:Static Расширение разметки поддерживается классомStaticExtension. Класс имеет одно свойство с именем Member типа string , заданного именем общедоступной константы, статического свойства, статического поля или элемента перечисления.

Один из способов использования x:Static — сначала определить класс с некоторыми константами или статическими переменными, такими как этот AppConstants класс:

static class AppConstants
{
    public static double NormalFontSize = 18;
}

Следующий код XAML демонстрирует наиболее подробный подход к созданию StaticExtension экземпляра класса между 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>

Средство синтаксического анализа XAML также позволяет StaticExtension классу быть сокращенным как x:Static:

<Label Text="Label No. 2">
    <Label.FontSize>
        <x:Static Member="local:AppConstants.NormalFontSize" />
    </Label.FontSize>
</Label>

Этот синтаксис можно упростить, поместив StaticExtension класс и параметр члена в фигурные скобки. Результирующее выражение устанавливается непосредственно атрибуту FontSize :

<Label Text="Label No. 3"
       FontSize="{x:StaticExtension Member=local:AppConstants.NormalFontSize}" />

В этом примере в фигурных скобках нет кавычек. Свойство MemberStaticExtension больше не является атрибутом XML. Он является частью выражения для расширения разметки.

Так же, как и при использовании его в качестве элемента объекта, его можно также сократить x:StaticExtensionx:Static в выражении в фигурных скобках:

<Label Text="Label No. 4"
       FontSize="{x:Static Member=local:AppConstants.NormalFontSize}" />

Класс StaticExtension имеет ContentProperty атрибут, ссылающийся на свойство Member, которое помечает это свойство как свойство содержимого по умолчанию класса. Для расширений разметки XAML, выраженных с фигурными скобками, можно исключить Member= часть выражения:

<Label Text="Label No. 5"
       FontSize="{x:Static local:AppConstants.NormalFontSize}" />

Это наиболее распространенная форма расширения разметки x:Static .

Корневой тег примера XAML также содержит объявление пространства имен XML для пространства имен .NET System . Это позволяет Label задать размер шрифта статическим полем Math.PI. Это приводит к довольно маленькому тексту, поэтому Scale для свойства задано значение Math.E:

<Label Text="&#x03C0; &#x00D7; E sized text"
       FontSize="{x:Static sys:Math.PI}"
       Scale="{x:Static sys:Math.E}"
       HorizontalOptions="Center" />

На следующем снимку экрана показаны выходные данные XAML:

x:Static demo.

Расширение разметки x:Reference

x:Reference Расширение разметки поддерживается классомReferenceExtension. Класс имеет одно свойство с именем Name типа string , которое вы задаете имя элемента на странице с именем x:Name. Это Name свойство является свойством содержимого ReferenceExtension, поэтому Name= не требуется при x:Reference отображении в фигурных скобках. x:Reference Расширение разметки используется исключительно с привязками данных. Дополнительные сведения о привязках данных см. в разделе "Привязка данных".

В следующем примере XAML показано два использования x:Reference с привязками данных, первое, где оно используется для задания Source свойства объекта, а второй — для задания BindingContext свойства Binding для двух привязок данных:

<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 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 BindingContext="{x:Reference slider}"
               Text="{Binding Value, StringFormat='{0:F0}&#x00B0; rotation'}"
               Rotation="{Binding Value}"
               FontSize="24"
               HorizontalOptions="Center"
               VerticalOptions="Center" />        
    </StackLayout>
</ContentPage>

В этом примере оба x:Reference выражения используют сокращенную версию ReferenceExtension имени класса и устраняют Name= часть выражения. В первом примере x:Reference расширение разметки внедрено в Binding расширение разметки, а SourceStringFormat свойства разделяются запятыми.

На следующем снимку экрана показаны выходные данные XAML:

x:Reference demo.

Расширение разметки x:Type

x:Type Расширение разметки является эквивалентом XAML ключевое слово C# typeof . Он поддерживается классом TypeExtension , который определяет свойство с именем TypeName типа string , которое должно быть присвоено имени класса или структуры. x:Type Расширение разметки возвращает Type объект этого класса или структуры. TypeName — свойство содержимого TypeExtension, поэтому TypeName= не требуется при x:Type появлении фигурных скобок.

x:Type Расширение разметки обычно используется с расширением x:Array разметки. Дополнительные сведения см. в расширении разметки x:Array.

В следующем примере XAML демонстрируется использование x:Type расширения разметки для создания экземпляров объектов .NET MAUI и их добавления в StackLayout. XAML состоит из трех Button элементов со своими Command свойствами, равными a Binding , и CommandParameter свойства, заданные для типов трех представлений .NET MAUI:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MarkupExtensions.TypeDemoPage"
             Title="x:Type Demo">    
    <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>

Файл программной части определяет и инициализирует 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;
    }
}

Button При нажатии нового экземпляра CommandParameter аргумента создается и добавляется в нееStackLayout. Затем три Button объекта совместно используют страницу с динамически созданными представлениями:

x:Type demo.

Расширение разметки x:Array

Расширение x:Array разметки позволяет определить массив в разметке. Он поддерживается классом ArrayExtension , который определяет два свойства:

  • Type тип Type, указывающий тип элементов в массиве. Это свойство должно иметь расширение разметки x:Type .
  • Items тип IList, который представляет собой коллекцию самих элементов. Это свойство содержимого ArrayExtension.

x:Array Расширение разметки никогда не отображается в фигурных скобках. Вместо этого начальные x:Array и конечные теги разделяют список элементов.

В следующем примере XAML показано, как добавлять x:Array элементы в ListView массив, задав ItemsSource свойство массиву:

<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>
                <ViewCell>
                    <BoxView Color="{Binding}"
                             Margin="3" />
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>     

В этом примере ViewCell создается простая BoxView для каждой записи цвета:

x:Array demo.

Примечание.

При определении массивов распространенных типов, таких как строки или числа, используйте теги языка XAML, перечисленные в аргументах Pass.

Расширение разметки x:NULL

x:Null Расширение разметки поддерживается классомNullExtension. Он не имеет свойств и является просто эквивалентом XAML ключевое слово C# null .

В следующем примере XAML показано, как использовать расширение разметки 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>      

В этом примере неявное Style определяется для Label этого, включающее SetterFontFamily свойство в определенный шрифт. Однако третий Label избегает использования шрифта, определенного в неявном стиле, задав для нее значение FontFamilyx:Null:

x:Null demo.

Расширение разметки DataTemplate

DataTemplate Расширение разметки позволяет преобразовать тип в типDataTemplate. Он поддерживается классомDataTemplateExtension, который определяет TypeName свойство типаstring, которое присваивается имени типа, преобразованного в .DataTemplate Свойство TypeName является свойством содержимого DataTemplateExtension. Таким образом, для выражений разметки XAML с фигурными скобками можно исключить часть TypeName= выражения.

Примечание.

Средство синтаксического анализа XAML позволяет сократить класс DataTemplateExtension как DataTemplate.

Обычное использование этого расширения разметки в приложении Shell, как показано в следующем примере:

<ShellContent Title="Monkeys"
              Icon="monkey.png"
              ContentTemplate="{DataTemplate views:MonkeysPage}" />

В этом примере MonkeysPage преобразуется из объекта в ContentPage объект DataTemplate, который задается в качестве значения ShellContent.ContentTemplate свойства. Это гарантирует, что MonkeysPage создается только при переходе на страницу, а не при запуске приложения.

Дополнительные сведения о приложениях Оболочки см. в разделе Shell.