# 03-设置系统集成 设置系统允许插件在阑山桌面的设置窗口中添加自己的配置页面,让用户可以自定义插件行为。 --- ## 🎯 设置系统概述 阑山桌面提供两种设置页面模式: | 模式 | 适用场景 | 复杂度 | 灵活性 | |-----|---------|--------|--------| | **声明式设置** | 简单的键值配置 | 低 | 中 | | **自定义设置页** | 复杂交互、自定义控件 | 中 | 高 | --- ## 📝 声明式设置 通过链式 API 声明配置项,宿主自动生成设置页面。 ### 基本用法 ```csharp public override void Initialize(HostBuilderContext context, IServiceCollection services) { services.AddPluginSettingsSection( sectionId: "myplugin-settings", // 设置节唯一标识 displayName: "我的插件设置", // 显示名称 configure: section => // 配置设置项 { section .AddToggle("enabled", "启用插件", defaultValue: true) .AddText("api_key", "API密钥", defaultValue: "") .AddNumber("interval", "刷新间隔(秒)", defaultValue: 60, minimum: 10, maximum: 3600) .AddSelect("theme", "主题", new[] { new SettingsOptionChoice("light", "浅色"), new SettingsOptionChoice("dark", "深色"), new SettingsOptionChoice("auto", "跟随系统") }, defaultValue: "auto"); }, iconKey: "Settings"); // 图标 } ``` ### 支持的设置类型 | 方法 | 类型 | 用途 | 示例 | |-----|------|------|------| | `AddToggle` | 布尔 | 开关选项 | 启用/禁用 | | `AddText` | 字符串 | 文本输入 | API密钥、用户名 | | `AddNumber` | 数值 | 数字输入 | 刷新间隔、数量 | | `AddSelect` | 枚举 | 下拉选择 | 主题、语言 | | `AddPath` | 路径 | 文件/文件夹选择 | 保存路径 | | `AddList` | 列表 | 字符串列表 | 服务器地址列表 | ### 各类型详解 #### Toggle(开关) ```csharp .AddToggle( key: "auto_update", // 设置键 displayName: "自动更新", // 显示名称 defaultValue: true, // 默认值 description: "启动时检查更新" // 可选描述 ) ``` #### Text(文本) ```csharp .AddText( key: "api_key", displayName: "API密钥", defaultValue: "", placeholder: "请输入API密钥", // 占位符 isPassword: true // 密码输入(掩码显示) ) ``` #### Number(数值) ```csharp .AddNumber( key: "refresh_interval", displayName: "刷新间隔", defaultValue: 60, minimum: 10, // 最小值 maximum: 3600, // 最大值 increment: 10 // 步进值 ) ``` #### Select(选择) ```csharp .AddSelect( key: "display_mode", displayName: "显示模式", choices: new[] { new SettingsOptionChoice("compact", "紧凑"), new SettingsOptionChoice("normal", "标准"), new SettingsOptionChoice("detailed", "详细") }, defaultValue: "normal" ) ``` #### Path(路径) ```csharp .AddPath( key: "save_location", displayName: "保存位置", defaultValue: "", pathType: SettingsPathType.Folder, // Folder 或 File dialogTitle: "选择保存文件夹" ) ``` --- ## 🎨 自定义设置页 当声明式设置无法满足需求时,可以创建自定义设置页面。 ### 步骤 1:创建设置页类 ```csharp using LanMountainDesktop.PluginSdk; using FluentAvalonia.UI.Controls; namespace MyPlugin; public class MySettingsPage : SettingsPageBase { private readonly IPluginSettingsService _settingsService; public MySettingsPage(IPluginSettingsService settingsService) { _settingsService = settingsService; InitializeComponent(); } private void InitializeComponent() { // 创建页面内容 var panel = new StackPanel { Spacing = 16 }; // 添加自定义控件 var expander = new SettingsExpander { Header = "高级设置", Description = "配置插件的高级选项" }; var toggle = new ToggleSwitch { Content = "启用实验性功能" }; expander.Items.Add(toggle); panel.Children.Add(expander); // 添加颜色选择器示例 var colorPicker = new ColorPicker { Header = "主题颜色" }; panel.Children.Add(colorPicker); Content = panel; } } ``` ### 步骤 2:注册自定义设置页 ```csharp public override void Initialize(HostBuilderContext context, IServiceCollection services) { services.AddPluginSettingsSection( sectionId: "myplugin-advanced", displayName: "高级设置", iconKey: "Settings"); } ``` ### 混合模式 可以同时使用声明式设置和自定义视图: ```csharp services.AddPluginSettingsSection( sectionId: "myplugin-settings", displayName: "插件设置", configure: section => section .SetCustomView() // 设置自定义视图 .AddToggle("enabled", "启用") // 同时声明设置项 .AddText("api_key", "API密钥"), iconKey: "Settings"); ``` --- ## 💾 读取和保存设置 ### 在服务中读取设置 ```csharp public class WeatherService { private readonly IPluginSettingsService _settings; public WeatherService(IPluginSettingsService settings) { _settings = settings; // 读取设置 var apiKey = _settings.GetValue("api_key", ""); var autoRefresh = _settings.GetValue("auto_update", true); var interval = _settings.GetValue("refresh_interval", 60); // 监听设置变化 _settings.SettingsChanged += (sender, e) => { if (e.Key == "refresh_interval") { UpdateTimerInterval(e.NewValue); } }; } } ``` ### 在组件中读取设置 ```csharp public class WeatherWidget : Border { public WeatherWidget(PluginDesktopComponentContext context) { // 通过 context 获取设置 var settings = context.Settings; var city = settings.GetValue("city", "北京"); var unit = settings.GetValue("temperature_unit", "celsius"); // 监听设置变化 context.Settings.SettingsChanged += (_, e) => { if (e.Key == "city") { RefreshWeather(e.NewValue); } }; } } ``` ### 保存设置 ```csharp // 在设置页面中保存 private void SaveButton_Click(object? sender, RoutedEventArgs e) { _settingsService.SetValue("api_key", ApiKeyTextBox.Text); _settingsService.SetValue("auto_update", AutoUpdateToggle.IsChecked ?? false); // 设置会自动持久化,无需手动保存文件 } ``` --- ## 🔔 设置变更通知 ### 订阅变更事件 ```csharp public class MyService { public MyService(IPluginSettingsService settings) { settings.SettingsChanged += OnSettingsChanged; } private void OnSettingsChanged(object? sender, SettingsChangedEvent e) { Console.WriteLine($"设置变更: {e.Key}"); Console.WriteLine($"旧值: {e.OldValue}"); Console.WriteLine($"新值: {e.NewValue}"); // 根据变更的键执行相应操作 switch (e.Key) { case "refresh_interval": UpdateRefreshTimer((int)e.NewValue); break; case "theme": ApplyTheme((string)e.NewValue); break; } } } ``` --- ## 🐛 常见问题 ### 问题 1:设置不保存 **排查:** 1. 确认 `sectionId` 唯一且合法 2. 检查设置键名是否正确 3. 查看日志是否有权限错误 ### 问题 2:设置页面不显示 **排查:** 1. 确认已调用 `AddPluginSettingsSection` 2. 检查 `sectionId` 是否唯一 3. 确认设置页类是 `public` ### 问题 3:设置变更通知不触发 **原因:** 可能订阅的是不同实例 **解决:** 确保使用注入的 `IPluginSettingsService` --- ## 📚 参考资源 - [IPluginSettingsService 源码](../../LanMountainDesktop.PluginSdk/IPluginSettingsService.cs) - [SettingsPageBase 源码](../../LanMountainDesktop.PluginSdk/SettingsPageBase.cs) - [04-开发设置页面](../04-实战案例/04-开发设置页面.md) --- ## 🎯 下一步 学习外观系统: 👉 **[04-外观与主题系统](04-外观与主题系统.md)** - 适配宿主主题 --- *最后更新:2026年4月*