IAppearanceService¶
IAppearanceService предоставляет платформенно-независимый способ получить параметры внешнего вида, поддерживаемые темой DeltaDesign, и применить выбранный. Он позволяет ViewModel менять вариант темы, цветовую палитру и плотность размещения во время работы приложения, не ссылаясь напрямую ни на какие типы UI-фреймворка.
Основные возможности:
- Варианты темы — Предоставляет доступ к доступным вариантам темы (
LightиDark). - Цветовые палитры — Предоставляет доступ к цветовым палитрам темы DeltaDesign, таким как
Nova,Helios,Terra,VegaиAtlas. - Плотность размещения — Предоставляет доступ к вариантам плотности размещения темы DeltaDesign (
Compact,StandardиSpacious). - Немедленное применение — Изменение соответствующего параметра
IAppearanceServiceсразу же меняет соответствующую настройку темы. - Привязка к селекторам — Сервис реализует интерфейс
INotifyPropertyChangedи предназначен для прямой привязки к галерее ленты, выпадающему списку, меню или любому другому селектору.
Определение интерфейса¶
public interface IAppearanceService : INotifyPropertyChanged
{
// A list of available theme variants (light/dark).
IReadOnlyList<IAppearanceOption> ThemeVariants { get; }
// A list of available color palettes.
IReadOnlyList<IAppearanceOption> Palettes { get; }
// A list of available layout densities.
IReadOnlyList<IAppearanceOption> Densities { get; }
// The chosen theme variant. Assigning it recolors the running application at once.
IAppearanceOption SelectedThemeVariant { get; set; }
// The chosen theme palette. Assigning it recolors the running application at once.
IAppearanceOption SelectedPalette { get; set; }
// The chosen density. Assigning it resizes the controls of the running application at once.
IAppearanceOption SelectedDensity { get; set; }
}
IAppearanceOption¶
Каждый элемент списков ThemeVariants, Palettes и Densities реализует интерфейс IAppearanceOption:
Как и другие интерфейсы сервисов, интерфейс IAppearanceOption не содержит типов UI-фреймворка. В нём есть только строковое свойство, задающее подпись параметра темы. Однако фактические реализации интерфейса IAppearanceOption возвращают более богатые объекты, перечисленные ниже:
Реализация IAppearanceOption |
Описание |
|---|---|
Класс ThemeOption |
Светлый или тёмный вариант темы. Дополнительные свойства: - ThemeOption.Variant — Avalonia.Styling.ThemeVariant, применяемый при выборе этого параметра. |
Класс PaletteOption |
Цветовая палитра. Дополнительные свойства: - PaletteOption.Palette — палитра, применяемая при выборе этого параметра (Nova, Helios, Terra, Vega, Atlas и т. д.);- PaletteOption.Accent — кисть только для чтения, представляющая акцентный цвет палитры. Свойство PaletteOption.Accent позволяет показать в селекторе образец цвета, чтобы пользователь мог оценить палитру до её выбора. |
Класс DensityOption |
Плотность размещения. Дополнительные свойства: - DensityOption.Density — плотность, применяемая при выборе этого параметра (Compact, Standard или Spacious). |
Реализация IAppearanceService возвращает эти более богатые объекты. Например, фактическое значение IAppearanceService.SelectedPalette — это объект PaletteOption.
Как использовать IAppearanceService¶
- В ViewModel предоставьте сервис
IAppearanceServiceв виде свойства. - В View привяжите контролы-селекторы к членам этого свойства.
Доступ к сервису¶
Чтобы предоставить сервис IAppearanceService в виде свойства, его нужно получить в ViewModel.
Получить объект IAppearanceService в ViewModel можно двумя способами:
- С помощью вспомогательного метода
Service<T>(). Это удобный способ получить зарегистрированные сервисы приложения, входящие в библиотеку Eremex Controls. - Через внедрение в конструктор.
Вспомогательный метод Service()¶
Реализуйте в ViewModel вспомогательный метод Service<T>(), который получает запрошенный сервис с помощью статического метода ApplicationServicesContext.GetRequiredService<T>().
using Eremex.AvaloniaUI.Controls.ApplicationServices;
using CommunityToolkit.Mvvm.Input;
public partial class MyViewModel : ObservableObject
{
// Provides access to any registered service
protected static T Service<T>() where T : class
=> ApplicationServicesContext.GetRequiredService<T>();
public IAppearanceService Appearance { get; } = Service<IAppearanceService>();
}
Убедитесь, что в файле App.axaml.cs сервисы приложения Eremex зарегистрированы с помощью SimpleServiceProvider и ApplicationServicesContext следующим образом:
public class App : Application
{
public override void OnFrameworkInitializationCompleted()
{
RegisterApplicationServices();
//...
}
static void RegisterApplicationServices()
{
// Register built-in services.
var serviceProvider = new SimpleServiceProvider();
ApplicationServicesContext.RegisterApplicationServices(serviceProvider.AddSingleton);
ApplicationServicesContext.SetCurrent(serviceProvider);
}
}
Внедрение в конструктор¶
Реализуйте в ViewModel конструктор с параметром типа IAppearanceService. При создании ViewModel передайте объект сервиса в этот конструктор.
public partial class MainViewModel : ObservableObject
{
public MainViewModel(IAppearanceService appearance)
{
Appearance = appearance;
}
public IAppearanceService Appearance { get; }
}
Предоставление сервиса из ViewModel¶
Предоставьте IAppearanceService в виде открытого свойства. Контролы в View будут привязываться к нему напрямую.
В этом примере создаётся свойство Appearance типа IAppearanceService, которое инициализируется с помощью вспомогательного метода Service<T>.
public partial class MainViewModel : ObservableObject
{
public IAppearanceService Appearance { get; }
public MainViewModel(ThemeVariant? startupThemeVariant = null)
{
Appearance = Service<IAppearanceService>();
Appearance.SelectedThemeVariant = FindTheme(startupThemeVariant);
//...
}
private IAppearanceOption? FindTheme(ThemeVariant? variant)
=> variant is null
? null
: Appearance.ThemeVariants.FirstOrDefault(
x => string.Equals(x.Header, variant.ToString(), StringComparison.OrdinalIgnoreCase));
// Provides access to any registered service
protected static T Service<T>() where T : class
=> ApplicationServicesContext.GetRequiredService<T>();
}
Пример - создание селектора палитры в View¶
В этом примере создаётся выпадающий список (контрол ComboBoxEditor) с доступными палитрами темы. При выборе элемента в выпадающем меню контрола соответствующая палитра применяется к приложению.
В этом примере:
ComboBoxEditor.ItemsSourceпривязано кAppearance.Palettes, чтобы показать все доступные палитры в выпадающем меню.ComboBoxEditor.EditorValueпривязано кAppearance.SelectedPalette. Выбор элемента в выпадающем меню контрола применяет соответствующую палитру темы.- Шаблон элемента ComboBoxEditor отображает акцентный цвет палитры в виде образца рядом с её названием (заголовком).
<mxe:ComboBoxEditor x:Name="themePaletteComboBox"
ItemsSource="{Binding Appearance.Palettes}"
EditorValue="{Binding Appearance.SelectedPalette}"
IsTextEditable="False"
ApplyItemTemplateToEditBox="True"
Width="150" Margin="0,0,10,0">
<mxe:ComboBoxEditor.ItemTemplate>
<DataTemplate x:DataType="appsvc:PaletteOption">
<StackPanel Orientation="Horizontal" Spacing="8">
<Border Width="12" Height="12" CornerRadius="2" VerticalAlignment="Center"
Background="{Binding Accent}"
BorderThickness="1"
BorderBrush="{DynamicResource Outline/Neutral/Transparent/Medium}"/>
<TextBlock Text="{Binding Header}" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</mxe:ComboBoxEditor.ItemTemplate>
</mxe:ComboBoxEditor>
Полный код приведён в демонстрационном приложении Controls Demo.
Пример - создание селектора плотности¶
В этом примере создаётся выпадающий список (контрол ComboBoxEditor), заполненный вариантами плотности размещения. При выборе элемента соответствующая плотность размещения применяется автоматически.
Чтобы показать в выпадающем списке собственные изображения для значений плотности, пример заполняет контрол элементами непосредственно из перечисления Eremex.AvaloniaUI.Themes.DeltaDesign.Density. Изображения предоставляются собственным конвертером NameToImageConverter и отображаются с помощью свойства ComboBoxEditor.ItemTemplate.
<mxe:ComboBoxEditor x:Name="densityComboBox"
ItemsSource="{mxc:EnumItemsSource EnumType=ddt:Density, ShowImages=True,
NameToImageConverter={views:DensityToIconConverter}}"
EditorValueChanged="DensityComboBoxEditor_EditorValueChanged"
IsTextEditable="False"
Margin="0,0,10,0">
<mxe:ComboBoxEditor.ItemTemplate>
<DataTemplate x:DataType="mxc:EnumMemberInfo">
<StackPanel Orientation="Horizontal" Spacing="8">
<Image Source="{Binding Image}" Stretch="None" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Name}" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</mxe:ComboBoxEditor.ItemTemplate>
</mxe:ComboBoxEditor>
Полный код приведён в демонстрационном приложении Controls Demo.
Изменение настроек темы в коде¶
Чтобы изменить настройки темы в коде, используйте свойства SelectedThemeVariant, SelectedPalette и SelectedDensity.
public IAppearanceService Appearance { get; } = Service<IAppearanceService>();
public void ChangeThemeSettings()
{
Appearance.SelectedThemeVariant = Appearance.ThemeVariants[0]; // Switch to the default theme variant.
Appearance.SelectedPalette = Appearance.Palettes[2]; // Apply the third palette.
Appearance.SelectedDensity = Appearance.Densities[0]; // Switch to the most compact density.
}
* Эта страница переведена с использованием технологий машинного перевода.