Стили

Последнее обновление: 18.12.2022

Стили представляют набор свойств и их значений, которые могут применяться к элементам. Основная задача стилей - создать стилевое единообразие для элементов интерфейса. Стили хранятся в ресурсах и отделяют стилизацию элементов от пользовательского интерфейса.

Чтобы понять, как стили упрощают нам работу, рассмотрим простой пример:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
    <StackLayout Padding="20">
        <Button Text="iOS" TextColor="#004D40" BackgroundColor="#80CBC4" Margin="10" />
        <Button Text="Android" TextColor="#004D40" BackgroundColor="#80CBC4" Margin="10" />
    </StackLayout>
</ContentPage>

Здесь определены две кнопки, которые фактически имеют один и тот же стиль: одни и те же цвет фона и текста, а также размер внешних отступов. Единственное отличие состоит в тексте кнопки.

Однако в данном случае мы вынуждены повторяться и повторно определять один и те же свойства и одни и те же значения для каждого из элементов.

Стили в .NET MAUI и C#

Теперь применим стили:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="buttonStyle" TargetType="Button">
                <Setter Property="TextColor" Value="#004D40" />
                <Setter Property="BackgroundColor" Value="#80CBC4" />
                <Setter Property="Margin" Value="10" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout Padding="20">
        <Button Text="iOS" Style="{StaticResource buttonStyle}" />
        <Button Text="Android" Style="{StaticResource buttonStyle}" />
    </StackLayout>
</ContentPage>

Стиль создается как ресурс с помощью объекта Style и, как любой другой ресурс, он обязательно должен иметь ключ. Атрибут TargetType указывает, к какому типу оносится стиль. В данном случае это тип Button.

С помощью коллекции Setters определяется группа свойств, входящих в стиль. В нее входят объекты Setter, которые имеют следующие свойства:

  • Property: указывает на свойство, к которому будет применять данный сеттер. При этом свойство должно представлять тип BindableProperty

  • Value: собственно значение свойства

Поскольку стиль определяется как ресурс, то для его установки используются расширения StaticResource или DynamicResource (если стиль динамический):

<Button Text="iOS" Style="{StaticResource buttonStyle}" />
<Button Text="Android" Style="{DynamicResource buttonStyle}" />

Иногда свойство может представлять сложный объект, либо же значение формируется сложным способом. Например, у класса Color есть конструктор, который принимет три значения int для трех составляющих цвет: красной, зеленой и синей компоненты. В этом случае мы можем расписать формирование объекта:

<Style x:Key="buttonStyle" TargetType="Button">
    <Setter Property="TextColor">
        <Setter.Value>
            <Color>
                <x:Arguments>
                    <x:Int32>0</x:Int32>
                    <x:Int32>75</x:Int32>
                    <x:Int32>25</x:Int32>
                </x:Arguments>
            </Color>
        </Setter.Value>
    </Setter>
    <Setter Property="BackgroundColor" Value="#80CBC4" />
    <Setter Property="Margin" Value="10" />
</Style>

Также в качестве значения можно устанавливать ссылку на другой ресурс:

<ContentPage.Resources>
    <ResourceDictionary>
      <Color x:Key="greenColor">#004D40</Color>
      <Style x:Key="buttonStyle" TargetType="Button">
        <Setter Property="TextColor" Value="{StaticResource Key=greenColor}" />
        <Setter Property="BackgroundColor" Value="#80CBC4" />
        <Setter Property="Margin" Value="10" />
      </Style>
    </ResourceDictionary>
</ContentPage.Resources>

TargetType

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

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
    <ContentPage.Resources>
        <Style TargetType="Button">
            <Setter Property="TextColor" Value="#004D40" />
            <Setter Property="BackgroundColor" Value="#80CBC4" />
            <Setter Property="Margin" Value="10" />
        </Style>
    </ContentPage.Resources>
    <StackLayout Padding="20">
        <Button Text="iOS" />
        <Button Text="Android" />
    </StackLayout>
</ContentPage>

Теперь у кнопок не надо будет указывать ресурс стиля, так как стиль будет автоматически применяться ко всем объектам типа, который указан в атрибуте TargetType.

Переопределение стилей

Стиль позволяет задать некоторые начальные значения. Однако элемент может переопределить отдельные значения из стиля:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
    <ContentPage.Resources>
        <Style x:Key="buttonStyle" TargetType="Button">
            <Setter Property="TextColor" Value="#004D40" />
            <Setter Property="BackgroundColor" Value="#80CBC4" />
            <Setter Property="Margin" Value="10" />
        </Style>
    </ContentPage.Resources>
    <StackLayout Padding="20">
        <Button Text="iOS" Style="{StaticResource buttonStyle}" />
        <Button Text="Android" Style="{StaticResource buttonStyle}" BackgroundColor="#B2EBF2" />
    </StackLayout>
</ContentPage>

В данном случае кнопка получает все значения из стиля buttonStyle, однако переопределяет цвет текста, так как прямое использование атрибутов элемента имеет приоритет над применяемым стилем.

переопределение стилей в .NET MAUI и C#

Установка стилей в коде

Для создания стиля в коде используется объект Style:

namespace HelloApp
{
    class StartPage : ContentPage
    {
        public StartPage()
        {
            Style buttonStyle = new Style(typeof(Button))
            {
                Setters =
                {
                    new Setter
                    {
                        Property = Button.TextColorProperty,
                        Value = Color.FromArgb("#004D40")
                    },
                    new Setter
                    {
                        Property = Button.BackgroundColorProperty,
                        Value = Color.FromArgb("#80CBC4")
                    },
                    new Setter
                    {
                        Property = Button.MarginProperty,
                        Value = 10
                    }
                }
            };

            Button button1 = new Button { Text = "iOS", Style = buttonStyle };
            Button button2 = new Button { Text = "Android", Style = buttonStyle };

            Content = new StackLayout
            {
                Padding = 20,
                Children = { button1, button2 }
            };
        }
    }
}

В конструктор объекта Style передается тип, для которого предназначен данный стиль - аналогично использованию атрибута TargetType в XAML.

При создании стиля в коде следует учитывать, что в качестве свойств указываются именно BindableProperty (как правило называется по имени обычного свойства с суффиксом Property). Например:

Property = Button.TextColorProperty

А не просто TextColor. Причем в начале идет тип (в данном случае Button), а потом идет название свойства (здесь TextColorProperty).

Наследование стилей

С помощью свойства BasedOn можно наследовать один стиль от другого. Например:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.MainPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="baseButtonStyle" TargetType="Button">
                <Setter Property="Margin" Value="10" />
                <Setter Property="WidthRequest" Value="120" />
                <Setter Property="TextColor" Value="#01579B" />
                <Setter Property="BackgroundColor" Value="#fff" />
            </Style>
            <Style x:Key="greenButtonStyle" TargetType="Button" BasedOn="{StaticResource baseButtonStyle}">
                <Setter Property="TextColor" Value="#004D40" />
                <Setter Property="BackgroundColor" Value="#80CBC4" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout Padding="20">
        <Button Text="iOS" Style="{StaticResource baseButtonStyle}" />
        <Button Text="Android" Style="{StaticResource greenButtonStyle}" />
    </StackLayout>
</ContentPage>

Здесь у стиля greenButtonStyle атрибут BasedOn указывает на другой стиль baseButtonStyle. И таким образом, стиль greenButtonStyle будет перенимать все установки от baseButtonStyle. При этом наследующий стиль может переопределить значения из наследуемого. В частости, здесь переопределяется значение свойства TextColor и BackgroundColor.

При наследовании стилей важно, чтобы тип элементов, указанный в качестве значения атрибута TargetType, совпадал. Например, в данном случае оба стиля применяется к элементам типа Button.

Наследование в коде C# осуществляется с помощью установки у стиля свойства BasedOn:

Style basedStyle = new Style(typeof(Button));
Style childStyle = new Style(typeof(Button))
{
    BasedOn = basedStyle
};

Встроенные стили

По умолчанию проект .NET MAUI уже содержит ряд встроенных стилей. Их можно найти в файле Styles.xaml в папке Resources/Styles:

Встроенные стили в проекте .NET MAUI и C#

Эти стили подключаются в качестве глобальных ресурсов в файле App.xaml и предоставляют базую стилизацию для некоторых элементов.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850