Udostępnij za pośrednictwem


Korzystanie z rozszerzeń znaczników XAML

Przeglądaj przykład. Przeglądaj przykład

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:

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="&#x03C0; &#x00D7; 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:Static demo.

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}&#x00B0; 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:Demo referencyjne.

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:

x:Typ demo.

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 typu Type, co wskazuje na typ elementów w tablicy. Ta właściwość powinna być ustawiona na rozszerzenie znaczników x:Type.
  • Items typu IList, 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:

x:Array demo.

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:

pokaz 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.