Udostępnij za pośrednictwem


Wprowadzenie do języka XAML

Browse sample.Przeglądaj przykład. Przeglądanie przykładu

W aplikacji .NET Multi-platform App UI (.NET MAUI), XAML jest najczęściej używany do definiowania elementów wizualnych strony i współpracuje z plikiem kodu w języku C#. Plik zaplecza zapewnia obsługę kodu dla znaczników. Te dwa pliki współtworzyją nową definicję klasy, która obejmuje widoki podrzędne i inicjowanie właściwości. W pliku XAML klasy i właściwości odwołują się do elementów i atrybutów XML, a linki między znacznikami i kodem są ustanawiane.

Anatomia pliku XAML

Nowa aplikacja MAUI platformy .NET zawiera trzy pliki XAML i ich skojarzone pliki kodu.

Screenshot of the structure of a new .NET MAUI app.Zrzut ekranu struktury nowej aplikacji .NET MAUI.

Pierwszą parą plików jest App.xaml, plik XAML, i App.xaml.cs, plik w języku C# zawierający logikę związaną z plikiem XAML. Zarówno App.xaml , jak i App.xaml.cs współtworzyć klasę o nazwie App , która pochodzi z Applicationklasy . Drugą parą plików są AppShell.xaml i AppShell.xaml.cs, które współtworzą klasę o nazwie AppShell, wywodzącą się z klasy Shell. Większość innych klas z plikami XAML przyczynia się do klasy, która dziedziczy z ContentPage i definiuje interfejs użytkownika strony. Dotyczy to plików MainPage.xaml i MainPage.xaml.cs.

Plik MainPage.xaml ma następującą strukturę:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyMauiApp.MainPage">
    ...
</ContentPage>

Dwie deklaracje przestrzeni nazw XML (xmlns) odnoszą się do URIs na stronie microsoft.com. Jednak w tych identyfikatorach URI nie ma zawartości i zasadniczo działają one jako identyfikatory wersji.

Pierwsza deklaracja przestrzeni nazw XML oznacza, że tagi zdefiniowane w pliku XAML bez prefiksu odwołują się do klas w .NET MAUI, na przykład ContentPage. Druga deklaracja przestrzeni nazw definiuje prefiks x. Jest to używane w przypadku kilku elementów i atrybutów, które są wewnętrzne dla samego języka XAML i które są obsługiwane przez inne implementacje języka XAML. Jednak te elementy i atrybuty różnią się nieco w zależności od roku osadzonego w identyfikatorze URI. Program .NET MAUI obsługuje specyfikację XAML 2009.

Na końcu pierwszego tagu x prefiks jest używany dla atrybutu o nazwie Class. Ponieważ użycie tego x prefiksu jest praktycznie uniwersalne dla przestrzeni nazw XAML, atrybuty XAML, takie jak Class są prawie zawsze określane jako x:Class. Atrybut x:Class określa w pełni kwalifikowaną nazwę klasy .NET: klasę MainPage w przestrzeni nazw MyMauiApp. Oznacza to, że ten plik XAML definiuje nową klasę o nazwie MainPage w przestrzeni nazw MyMauiApp, która dziedziczy po ContentPage (tag, w którym pojawia się atrybut x:Class).

Atrybut x:Class może być wyświetlany tylko w elemecie głównym pliku XAML w celu zdefiniowania pochodnej klasy języka C#. Jest to jedyna nowa klasa zdefiniowana w pliku XAML. Wszystkie inne elementy wyświetlane w pliku XAML są po prostu tworzone z istniejących klas i inicjowane.

Plik MainPage.xaml.cs wygląda podobnie jak poniżej:

namespace MyMauiApp;

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }
}

Klasa MainPage pochodzi z ContentPageklasy i jest definicją klasy częściowej.

Kiedy Visual Studio tworzy projekt, generator źródłowy tworzy nowy kod źródłowy C#, który zawiera definicję metody InitializeComponent, wywoływanej z konstruktora MainPage, i dodaje go do obiektu kompilacji.

W czasie wykonywania kod w klasie MauiProgram uruchamia aplikację i wykonuje konstruktor klasy App, który tworzy wystąpienie klasy AppShell. Klasa AppShell tworzy wystąpienie pierwszej strony aplikacji do wyświetlenia, którą jest MainPage. Konstruktor MainPage wywołuje InitializeComponent metodę, która inicjuje wszystkie obiekty zdefiniowane w pliku XAML, łączy je razem w relacje nadrzędny-podrzędny, dołącza obsługi zdarzeń zdefiniowane w kodzie do zdarzeń ustawionych w pliku XAML i wstawia wynikowe drzewo obiektów jako zawartość strony.

Uwaga

Klasa AppShell używa .NET MAUI Shell do ustawienia pierwszej strony aplikacji, która ma być wyświetlana. Jednak powłoka wykracza poza zakres tego wprowadzenia do języka XAML. Aby uzyskać więcej informacji, odwiedź .NET MAUI Shell.

Ustawianie zawartości strony

ContentPage powinien zawierać jedno dziecko, które może być widokiem lub układem z widokami dziećmi. Element podrzędny ContentPage jest automatycznie ustawiany jako wartość właściwości ContentPage.Content.

Poniższy przykład przedstawia ContentPage zawierający Label:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.HelloXamlPage"
             Title="Hello XAML Page">
    <Label Text="Hello, XAML!"
           VerticalOptions="Center"
           HorizontalTextAlignment="Center"
           Rotation="-15"
           FontSize="18"
           FontAttributes="Bold"
           TextColor="Blue" />
</ContentPage>

W powyższym przykładzie relacja między klasami, właściwościami i kodem XML powinna być widoczna. Klasa .NET MAUI (na przykład ContentPage lub Label) pojawia się w pliku XAML jako element XML. Właściwości tej klasy, w tym Title na ContentPage oraz siedem właściwości Label, zwykle pojawiają się jako atrybuty XML.

Istnieje wiele skrótów, aby ustawić wartości tych właściwości. Niektóre właściwości to podstawowe typy danych. Na przykład Title i Text są typu string, a Rotation jest typu double. Właściwość HorizontalTextAlignment jest typu TextAlignment, który jest wyliczeniem. W przypadku właściwości dowolnego typu wyliczeniowego, wystarczy podać nazwę członka.

Jednak w przypadku właściwości bardziej złożonych typów konwertery są używane do analizowania kodu XAML. Są to klasy w .NET MAUI, które pochodzą z TypeConverter. W powyższym przykładzie kilka .NET MAUI konwerterów jest automatycznie stosowanych do konwertowania ciągów znaków na ich prawidłowy typ.

  • LayoutOptionsConverterVerticalOptions dla właściwości. Ten konwerter przekształca nazwy publicznych statycznych pól struktury LayoutOptions na wartości typu LayoutOptions.
  • dla właściwości. Ten konwerter przekształca nazwy publicznych statycznych pól klasy Colors lub wartości szesnastkowe RGB, z kanałem alfa lub bez niego.

Po uruchomieniu aplikacji .NET MAUI zazwyczaj wyświetla się MainPage. Aby wyświetlić inną stronę, możesz ustawić to jako nową stronę startową w AppShell.xaml, lub przejść do nowej strony z MainPage.

Aby zaimplementować nawigację, w konstruktorze MainPage.xaml.cs można utworzyć prosty i użyć programu obsługi zdarzeń do przejścia do .

public MainPage()
{
    InitializeComponent();

    Button button = new Button
    {
        Text = "Navigate!",
        HorizontalOptions = LayoutOptions.Center,
        VerticalOptions = LayoutOptions.Center
    };

    button.Clicked += async (sender, args) =>
    {
        await Navigation.PushAsync(new HelloXamlPage());
    };

    Content = button;
}

Po skompilowaniu i wdrożeniu nowej wersji tej aplikacji zostanie wyświetlony przycisk na ekranie. Naciśnięcie powoduje przejście do: HelloXamlPage

Zrzut ekranu obróconego tekstu etykiety.

Możesz wrócić do MainPage przy użyciu paska nawigacyjnego wyświetlanego na każdej platformie.

Uwaga

Alternatywą dla tego modelu nawigacji jest użycie powłoki MAUI platformy .NET. Aby uzyskać więcej informacji, zobacz omówienie powłoki .NET MAUI.

Interakcje między XAML a kodem

Element podrzędny większości ContentPage pochodnych jest układem, takim jak lub StackLayoutGrid, a układ może zawierać wiele elementów podrzędnych. W języku XAML te relacje nadrzędny-podrzędny są ustanawiane przy użyciu normalnej hierarchii XML.

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.XamlPlusCodePage"
             Title="XAML + Code Page">
    <StackLayout>
        <Slider VerticalOptions="Center" />
        <Label Text="A simple Label"
               FontSize="18"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <Button Text="Click Me!"
                HorizontalOptions="Center"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

Ten plik XAML jest syntaktycznie kompletny i tworzy następujący interfejs użytkownika:

Zrzut ekranu przedstawiający wiele kontrolek na stronie.Zrzut ekranu przedstawiający wiele kontrolek na stronie.

Jednak mimo że można wchodzić w interakcje z elementami Slider i Button, interfejs użytkownika nie jest aktualizowany. Slider powinien spowodować, że Label wyświetli bieżącą wartość, a Button powinien coś zrobić.

Slider Wyświetlanie wartości przy użyciu elementu Label można osiągnąć całkowicie w języku XAML za pomocą powiązania danych. Warto jednak najpierw zobaczyć rozwiązanie kodu. Mimo to, obsługa kliknięcia Button zdecydowanie wymaga kodu. Oznacza to, że plik code-behind dla XamlPlusCodePage musi zawierać programy obsługi dla zdarzenia ValueChanged elementu Slider oraz zdarzenia Clicked elementu Button.

namespace XamlSamples
{
    public partial class XamlPlusCodePage
    {
        public XamlPlusCodePage()
        {
            InitializeComponent();
        }

        void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
        {
            valueLabel.Text = args.NewValue.ToString("F3");
        }

        async void OnButtonClicked(object sender, EventArgs args)
        {
            Button button = (Button)sender;
            await DisplayAlert("Clicked!", "The button labeled '" + button.Text + "' has been clicked", "OK");
        }
    }
}
namespace XamlSamples
{
    public partial class XamlPlusCodePage
    {
        public XamlPlusCodePage()
        {
            InitializeComponent();
        }

        void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
        {
            valueLabel.Text = args.NewValue.ToString("F3");
        }

        async void OnButtonClicked(object sender, EventArgs args)
        {
            Button button = (Button)sender;
            await DisplayAlertAsync("Clicked!", "The button labeled '" + button.Text + "' has been clicked", "OK");
        }
    }
}

W pliku Slider XAML tagi i Button muszą zawierać atrybuty dla ValueChanged zdarzeń i Clicked odwołujących się do tych procedur obsługi:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.XamlPlusCodePage"
             Title="XAML + Code Page">
    <StackLayout>
        <Slider VerticalOptions="Center"
                ValueChanged="OnSliderValueChanged" />
        <Label x:Name="valueLabel"
               Text="A simple Label"
               FontSize="18"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <Button Text="Click Me!"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                Clicked="OnButtonClicked" />
    </StackLayout>
</ContentPage>

Zwróć uwagę, że przypisanie procedury obsługi do zdarzenia ma taką samą składnię, jak przypisanie wartości do właściwości. Ponadto, aby program obsługi zdarzeń Slider mógł używać Label do wyświetlania bieżącej wartości, musi odwoływać się do tego obiektu z kodu. W związku z tym Label wymaga nazwy, która jest określona z atrybutem x:Name . Prefiks atrybutu wskazuje, że ten atrybut jest właściwy dla XAML. Nazwa przypisana do atrybutu x:Name ma te same reguły co nazwy zmiennych języka C#. Na przykład musi zaczynać się od litery lub podkreślenia i nie zawierać osadzonych spacji.

Program ValueChanged obsługi zdarzeń może teraz ustawić Label wartość , aby wyświetlić nową Slider wartość, która jest dostępna z argumentów zdarzeń:

void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
    valueLabel.Text = args.NewValue.ToString("F3");
}

Alternatywnie, obsługa zdarzenia może uzyskać obiekt Slider, który generuje to zdarzenie, z argumentu zdarzenia sender i uzyskać właściwość Value z tego:

void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
    valueLabel.Text = ((Slider)sender).Value.ToString("F3");
}

Wynikiem jest to, że każda manipulacja Slider powoduje, że jego wartość jest wyświetlana w obiekcie Label:

Screenshot of multiple controls on a page, with Slider value displayed.Zrzut ekranu przedstawiający wiele kontrolek na stronie z wyświetloną wartością suwaka.

W powyższym przykładzie Button symuluje odpowiedź na zdarzenie Clicked, wyświetlając alert z Text przycisku. W związku z tym program obsługi zdarzeń może rzutować sender argument na element , a następnie uzyskać dostęp do Button jego właściwości:

async void OnButtonClicked(object sender, EventArgs args)
{
    Button button = (Button)sender;
    await DisplayAlert("Clicked!", "The button labeled '" + button.Text + "' has been clicked", "OK");
}

Metoda OnButtonClicked jest definiowana jako async, ponieważ metoda DisplayAlert jest asynchroniczna i powinna być poprzedzona operatorem await, który zwraca wartość po zakończeniu metody. Ponieważ ta metoda uzyskuje Button wyzwalanie zdarzenia z argumentu sender , można użyć tej samej procedury obsługi dla wielu przycisków.

async void OnButtonClicked(object sender, EventArgs args)
{
    Button button = (Button)sender;
    await DisplayAlertAsync("Clicked!", "The button labeled '" + button.Text + "' has been clicked", "OK");
}

Metoda OnButtonClicked jest definiowana jako async, ponieważ metoda DisplayAlertAsync jest asynchroniczna i powinna być poprzedzona operatorem await, który zwraca wartość po zakończeniu metody. Ponieważ ta metoda uzyskuje wywołanie zdarzenia z sender argumentu, tę samą procedurę obsługi można zastosować dla wielu przycisków.

Następne kroki

Język XAML jest głównie zaprojektowany do instancjonowania i inicjowania obiektów. Jednak często właściwości muszą być ustawione na obiekty złożone, których nie można łatwo przedstawić jako ciągów XML, a czasami właściwości zdefiniowane przez jedną klasę muszą być ustawione w klasie podrzędnej. Te dwie potrzeby wymagają podstawowych funkcji składni XAML elementów właściwości oraz właściwości dołączonych.