# 02-桌面组件系统 桌面组件(Desktop Component)是阑山桌面插件的核心功能。本文详细讲解组件系统的工作原理和开发方法。 --- ## 🎯 什么是桌面组件 桌面组件是显示在阑山桌面上的可视化元素,用户可以自由: - 添加/删除组件 - 拖动调整位置 - 调整大小 - 配置属性 **常见组件示例:** - 时钟组件 - 显示当前时间 - 天气组件 - 显示天气信息 - 日历组件 - 显示日期和日程 - 系统监控 - 显示 CPU/内存使用率 --- ## 📐 网格系统 阑山桌面使用网格系统管理组件布局。 ### 网格概念 ``` ┌─────────────────────────────────────────┐ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │ 2x2│ │ 2x2│ │ 2x2│ │ 2x2│ │ │ │ 格 │ │ 格 │ │ 格 │ │ 格 │ │ │ └────┘ └────┘ └────┘ └────┘ │ │ ┌────┐ ┌────────┐ ┌────┐ │ │ │ 2x2│ │ 4x2 │ │ 2x2│ │ │ │ 格 │ │ 格 │ │ 格 │ │ │ └────┘ └────────┘ └────┘ │ │ ┌────────┐ ┌────────┐ │ │ │ 4x3 │ │ 4x3 │ │ │ │ 格 │ │ 格 │ │ │ └────────┘ └────────┘ │ └─────────────────────────────────────────┘ 每格大小:约 60-80 像素(根据 DPI 自动调整) ``` ### 组件尺寸 组件尺寸以**格数**为单位: | 属性 | 说明 | 示例 | |-----|------|------| | `MinWidthCells` | 最小宽度(格数) | 4 = 4格宽 | | `MinHeightCells` | 最小高度(格数) | 3 = 3格高 | **常见尺寸参考:** | 组件类型 | 推荐尺寸 | 实际像素(约) | |---------|---------|--------------| | 小图标 | 2x2 | 120x120 | | 天气卡片 | 4x3 | 240x180 | | 时钟 | 4x4 | 240x240 | | 日历 | 6x4 | 360x240 | | 宽面板 | 8x3 | 480x180 | --- ## 🏗️ 创建组件 ### 步骤 1:创建组件类 组件是继承自 Avalonia 控件的类: ```csharp using Avalonia.Controls; using LanMountainDesktop.PluginSdk; namespace MyPlugin; public class WeatherWidget : Border // 继承自 Border 或其他控件 { public WeatherWidget(PluginDesktopComponentContext context) { // 组件初始化 InitializeComponent(context); } private void InitializeComponent(PluginDesktopComponentContext context) { // 设置背景 Background = new SolidColorBrush(Colors.Transparent); // 设置圆角(使用宿主主题) CornerRadius = context.Appearance.ResolveCornerRadius( PluginCornerRadiusPreset.Component); // 创建内容 var textBlock = new TextBlock { Text = "天气组件", HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; Child = textBlock; } } ``` ### 步骤 2:注册组件 在 `Plugin.Initialize` 中注册: ```csharp public override void Initialize(HostBuilderContext context, IServiceCollection services) { services.AddPluginDesktopComponent( new PluginDesktopComponentOptions { ComponentId = "MyPlugin.Weather", // 唯一标识 DisplayName = "天气", // 显示名称 IconKey = "Weather", // 图标(Fluent 图标名) Category = "工具", // 分类 MinWidthCells = 4, // 最小宽度(格) MinHeightCells = 3, // 最小高度(格) CornerRadiusPreset = PluginCornerRadiusPreset.Component // 圆角预设 }); } ``` ### PluginDesktopComponentOptions 详解 | 属性 | 必需 | 说明 | 示例 | |-----|------|------|------| | `ComponentId` | ✅ | 唯一标识符 | `"MyPlugin.Weather"` | | `DisplayName` | ✅ | 显示名称 | `"天气"` | | `IconKey` | ✅ | 图标键名 | `"Weather"`、`"Clock"` | | `Category` | ✅ | 分类 | `"工具"`、`"信息"` | | `MinWidthCells` | ✅ | 最小宽度(格) | `4` | | `MinHeightCells` | ✅ | 最小高度(格) | `3` | | `CornerRadiusPreset` | ❌ | 圆角预设 | `PluginCornerRadiusPreset.Component` | | `ResizeMode` | ❌ | 调整大小模式 | `PluginDesktopComponentResizeMode.Free` | ### 常用 Fluent 图标 | 图标键名 | 用途 | |---------|------| | `Weather` | 天气相关 | | `Clock` | 时钟、时间 | | `Calendar` | 日历、日期 | | `Settings` | 设置 | | `Home` | 主页 | | `Search` | 搜索 | | `Star` | 收藏 | | `Heart` | 喜欢 | | `Info` | 信息 | | `Warning` | 警告 | 完整图标列表:[Fluent UI System Icons](https://github.com/microsoft/fluentui-system-icons) --- ## 🎨 组件外观 ### 圆角设置 插件必须使用宿主提供的圆角系统,以保持视觉一致性: ```csharp public WeatherWidget(PluginDesktopComponentContext context) { // 获取组件标准圆角 var cornerRadius = context.Appearance.ResolveCornerRadius( PluginCornerRadiusPreset.Component); CornerRadius = cornerRadius; } ``` **可用的圆角预设:** | 预设 | 用途 | |-----|------| | `Micro` | 微小元素 | | `Xs` | 小元素 | | `Sm` | 小卡片 | | `Md` | 普通按钮/卡片 | | `Lg` | 大面板 | | `Xl` | 强调容器 | | `Component` | **桌面组件标准** | | `Default` | 自适应 | ### 背景与透明 ```csharp // 透明背景(推荐,让宿主壁纸透出) Background = new SolidColorBrush(Colors.Transparent); // 毛玻璃效果 Background = new SolidColorBrush(Color.Parse("#40FFFFFF")); // 纯色背景 Background = new SolidColorBrush(Color.Parse("#FF2D2D2D")); ``` ### 响应主题变化 ```csharp public WeatherWidget(PluginDesktopComponentContext context) { // 订阅主题变化 context.Appearance.AppearanceChanged += (_, _) => { UpdateAppearance(); }; UpdateAppearance(); } private void UpdateAppearance() { // 根据当前主题更新颜色 var isDark = Application.Current?.ActualThemeVariant == ThemeVariant.Dark; Foreground = new SolidColorBrush(isDark ? Colors.White : Colors.Black); } ``` --- ## 📏 尺寸与布局 ### 获取实际尺寸 ```csharp public WeatherWidget(PluginDesktopComponentContext context) { // 订阅尺寸变化 SizeChanged += OnSizeChanged; } private void OnSizeChanged(object? sender, SizeChangedEventArgs e) { // 获取当前实际尺寸(像素) var width = Bounds.Width; var height = Bounds.Height; // 根据尺寸调整内容 if (width < 200) { // 小尺寸模式 ShowCompactView(); } else { // 完整模式 ShowFullView(); } } ``` ### 自适应布局 ```csharp private void UpdateLayout() { var width = Bounds.Width; var height = Bounds.Height; // 根据宽高比调整布局 if (width > height * 2) { // 宽屏模式 - 水平排列 _layout.Orientation = Orientation.Horizontal; } else { // 正常模式 - 垂直排列 _layout.Orientation = Orientation.Vertical; } } ``` --- ## 🔄 组件生命周期事件 ```csharp public WeatherWidget(PluginDesktopComponentContext context) { // 组件加载完成(此时已添加到视觉树) Loaded += OnLoaded; // 组件卸载(用户删除或关闭宿主) Unloaded += OnUnloaded; // 尺寸变化 SizeChanged += OnSizeChanged; } private async void OnLoaded(object? sender, RoutedEventArgs e) { // 加载数据 await LoadDataAsync(); // 启动定时器 _timer = new Timer(OnTimerTick, null, TimeSpan.Zero, TimeSpan.FromMinutes(5)); } private void OnUnloaded(object? sender, RoutedEventArgs e) { // 清理资源 _timer?.Dispose(); _httpClient?.Dispose(); } ``` --- ## 💾 组件设置持久化 组件可以保存自己的设置: ```csharp public class WeatherWidget : Border { private readonly IComponentSettingsAccessor _settings; public WeatherWidget(PluginDesktopComponentContext context) { // 获取设置访问器 _settings = context.Settings; // 读取设置 var city = _settings.GetValue("city", defaultValue: "北京"); var autoRefresh = _settings.GetValue("auto_refresh", defaultValue: true); // 保存设置 _settings.SetValue("city", "上海"); } } ``` --- ## 🐛 常见问题 ### 问题 1:组件不显示在库中 **排查:** 1. 确认已调用 `AddPluginDesktopComponent` 2. 检查 `ComponentId` 是否唯一 3. 确认组件类是 `public` ### 问题 2:组件显示异常 **排查:** 1. 检查构造函数参数是否正确(需要 `PluginDesktopComponentContext`) 2. 确认没有抛出未处理异常 3. 查看日志文件 ### 问题 3:圆角不生效 **原因:** 插件无法访问宿主 XAML 资源 **解决:** 使用代码设置圆角(见上文) ### 问题 4:尺寸不正确 **排查:** 1. 检查 `MinWidthCells` 和 `MinHeightCells` 设置 2. 确认内容没有强制尺寸 --- ## 📚 参考资源 - [PluginDesktopComponentOptions 源码](../../LanMountainDesktop.PluginSdk/PluginDesktopComponentOptions.cs) - [04-外观与主题系统](04-外观与主题系统.md) - [01-开发天气组件](../04-实战案例/01-开发天气组件.md) --- ## 🎯 下一步 学习如何添加设置页面: 👉 **[03-设置系统集成](03-设置系统集成.md)** - 让用户配置你的组件 --- *最后更新:2026年4月*