Содержание
Стили в .NET MAUI позволяют отделить визуальное оформление элемента управления от его основного кода. Стиль в .NET MAUI представляет собой набор свойств и их значений, которые могут применяться к элементам управления.
Пример использования стилей в приложении .NET MAUI
Часто наши приложения содержат ряд однотипных элементов управления с одинаковым оформлением. Например, рассмотрим следующий XAML-код
<ScrollView>
<VerticalStackLayout>
<Button BackgroundColor="LightBlue"
TextColor="DarkBlue"
FontSize="14"
Text="Кнопка №1"
Padding="5"
Margin="5"/>
<Button BackgroundColor="LightBlue"
TextColor="DarkBlue"
FontSize="14"
Text="Кнопка №2"
Padding="5"
Margin="5"/>
</VerticalStackLayout>
</ScrollView>
Здесь две кнопки имеют абсолютно одинаковое оформление, различается только их текст.
В данном случае мы можем вынести стиль их оформления в отдельный объект, например, так:
<?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="StylesMaui.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Button" x:Key="button">
<Setter Property="BackgroundColor" Value="LightBlue"/>
<Setter Property="TextColor" Value="DarkBlue"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="Margin" Value="5"/>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ScrollView>
<VerticalStackLayout>
<Button Style="{StaticResource button}"
Text="Кнопка №1"/>
<Button Style="{StaticResource button}"
Text="Кнопка №2"/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Стили определяются точно также, как и обычные ресурсы. При этом, для их определения используется объект Style. Так как стиль определяется в словаре ресурсов, до мы должны задать для него свойство x:Key. Свойство Style.TargetType определяет тип объекта к которому будет применяться стиль. В нашем случае мы создаем стиль для кнопки Button с ключом button.
Далее, используя коллекцию Setters, мы добавляем в стиль элементы Setter, каждый из которых определяет свойство и его значение для объекта, указанного в TargetType. В нашем примере, мы опустили объявление свойства Setters и сразу перечислили необходимые элементы Setter. Полная запись стиля могла бы выглядеть так:
<Style TargetType="Button" x:Key="button">
<Style.Setters>
тут перечисляем все объекты Setter
</Style.Setters>
</Style>
Каждый объект Setter содержит два свойства:
Property— имя свойстваValue— его значение
Определив стиль, мы можем его использовать в приложение также, как и ресурсы, то есть с использованием расширений XAML StaticResource или DynamicResource и применяется это расширение к свойству Style элемента управления. В нашем случае, мы использовали стиль как статический и применили его к обеим кнопкам:
<Button Style="{StaticResource button}"
Text="Кнопка №1"/>
<Button Style="{StaticResource button}"
Text="Кнопка №2"/>
Теперь можно запустить приложение и убедиться, что внешний вид кнопок остался точно таким же, как и был.
Общие (неявные) стили
Если мы знаем, что определенный стиль будет применяться ко всем элементам управления одного типа (или, по крайней мере, к абсолютному большинству), то мы можем не указывать для стиля атрибут x:Key. В этом случае, стиль будет применяться автоматически ко всем элементам управления с типом, указанным в 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="StylesMaui.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Button">
<Style.Setters>
<Setter Property="BackgroundColor" Value="LightBlue"/>
<Setter Property="TextColor" Value="DarkBlue"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="Margin" Value="5"/>
</Style.Setters>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ScrollView>
<VerticalStackLayout>
<Button Text="Кнопка №1"/>
<Button Text="Кнопка №2"/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Так как наш стиль не имеет ключа x:Key, то он автоматически применяется ко всем кнопкам приложения.
Приоритет стилей
Стили элементов управления, как и ресурсы, могут определяться на разных уровнях иерархии: на уровне страницы, приложения и т.д. Более того, в приложении может быть определено несколько общих стилей для одного и того же типа элементов управления. Поэтому в .NET MAUI действует правило: стили, расположенные на более низком уровне иерархии имею более высокий приоритет. Например, изменим код нашего приложения следующим образом:
<?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="StylesMaui.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Button">
<Style.Setters>
<Setter Property="BackgroundColor" Value="LightBlue"/>
<Setter Property="TextColor" Value="DarkBlue"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="Margin" Value="5"/>
</Style.Setters>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ScrollView>
<VerticalStackLayout>
<VerticalStackLayout.Resources>
<ResourceDictionary>
<Style TargetType="Button">
<Style.Setters>
<Setter Property="BackgroundColor" Value="Coral"/>
<Setter Property="TextColor" Value="Pink"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="Margin" Value="5"/>
</Style.Setters>
</Style>
</ResourceDictionary>
</VerticalStackLayout.Resources>
<Button Text="Кнопка №1"/>
<Button Text="Кнопка №2"/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Здесь определены два общих стиля на разных уровнях:
- Стиль на уровне страницы
- Стиль на уровне макета (контейнера компоновки)
Так как стиль определенный на уровне макета находится ниже в иерархии, то он будет иметь более высокий приоритет. Поэтому, если запустить приложение, то вы увидите следующий вид кнопок:
Такое же поведение характерно и в том случае, если вы решите изменить одно или несколько свойств объекта, которые перечислены в стиле. Например,
<ScrollView>
<VerticalStackLayout>
<VerticalStackLayout.Resources>
<ResourceDictionary>
<Style TargetType="Button">
<Style.Setters>
<Setter Property="BackgroundColor" Value="Coral"/>
<Setter Property="TextColor" Value="Pink"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="Margin" Value="5"/>
</Style.Setters>
</Style>
</ResourceDictionary>
</VerticalStackLayout.Resources>
<Button Text="Кнопка №1" TextColor="Red" />
<Button Text="Кнопка №2"/>
</VerticalStackLayout>
</ScrollView>
Теперь цвет текста первой кнопки будет переопределен на красный:
Наследование стилей и классы стилей
Стили можно наследовать. Для этого используется свойство стиля BaseOn. Например,
<?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="StylesMaui.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Button" x:Key="baseStyle">
<Style.Setters>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="Margin" Value="5"/>
</Style.Setters>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ScrollView>
<VerticalStackLayout>
<VerticalStackLayout.Resources>
<ResourceDictionary>
<Style TargetType="Button" BasedOn="{StaticResource baseStyle}">
<Style.Setters>
<Setter Property="CornerRadius" Value="15"/>
<Setter Property="BackgroundColor" Value="Coral"/>
<Setter Property="TextColor" Value="Pink"/>
</Style.Setters>
</Style>
</ResourceDictionary>
</VerticalStackLayout.Resources>
<Button Text="Кнопка №1" />
<Button Text="Кнопка №2"/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Здесь стиль, расположенный на уровне макета, наследуется от стиля с ключом baseStyle. Теперь к оформлению кнопки будут применены все свойства из baseStyle плюс свойства из стиля уровня макета
Также, мы можем указывать класс стиля, чтобы разные стили можно было применять к одному типу элементов управления. Например,
<?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="StylesMaui.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="Button" Class="RoundedButton">
<Style.Setters>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="CornerRadius" Value="15"/>
<Setter Property="BackgroundColor" Value="Coral"/>
<Setter Property="TextColor" Value="Pink"/>
</Style.Setters>
</Style>
<Style TargetType="Button" Class="SimpleButton">
<Style.Setters>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="BackgroundColor" Value="LightBlue"/>
<Setter Property="TextColor" Value="DarkBlue"/>
</Style.Setters>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ScrollView>
<VerticalStackLayout>
<Button Text="Кнопка №1" StyleClass="RoundedButton" />
<Button Text="Кнопка №2" StyleClass="SimpleButton"/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Обратите внимание — для применения стиля к кнопкам мы используем свойство StyleClass в котором указываем необходимый класс стиля. Результат будет следующим:
Свойство StyleClass имеет тип IList<string>, поэтому мы можем применять к элементу управления сразу несколько классов стилей, например, так:
<Button Text="Кнопка №1" StyleClass="RoundedButton, SimpleButton" />
В результате, кнопка останется со скругленными углами (см. класс стиля RoundedButton), но изменит цвет:
Итого
Стили в .NET MAUI позволяют вынести визуальное оформление элементов управления в ресурсы, изолировав их при этом от основной части кода приложения. Стиль может применяться как ко всем элементам определенного типа, так и по отдельности. Для стилей можно определять классы, что позволяет применять к элементу управления несколько стилей одновременно.