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 中,将选择器控件绑定到该属性的成员。
访问服务¶
您需要在 ViewModel 中访问 IAppearanceService 服务,才能将其公开为属性。
在 ViewModel 中访问 IAppearanceService 对象有两种方式:
- 通过
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 文件中,确保按如下方式使用 SimpleServiceProvider 和 ApplicationServicesContext 注册 Eremex 应用程序服务:
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 中的 UI 控件将直接绑定到它。
以下示例创建一个 IAppearanceService 类型的 Appearance 属性,并使用 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>
完整代码请参阅 演示应用程序 应用程序。
示例 - 创建密度选择器¶
此示例创建一个填充了布局密度选项的组合框(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>
完整代码请参阅 演示应用程序 应用程序。
在代码中更改主题设置¶
使用 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.
}
* 本页面使用机器翻译技术翻译。