You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

144 KiB

修改记录

2025年修改记录

简化 run-linux.sh 启动脚本,移除不必要的 libSkiaSharp.so 删除逻辑

  • 日期: 2025年1月
  • 问题描述:
    • run-linux.sh 启动脚本中包含删除 libSkiaSharp.so 的逻辑
    • 但 SkiaSharp 版本冲突问题已经通过项目文件中的包引用解决
    • 不再需要手动删除库文件,脚本应该简化
  • 解决方案:
    • 移除删除 libSkiaSharp.so 的逻辑
    • 移除检查 runtimes/linux-x64/native/libSkiaSharp.so 的逻辑
    • 简化脚本,只保留必要的功能:检查可执行文件、设置权限、启动应用
    • 更新脚本注释,说明脚本的简化目的
  • 涉及文件:
    • AuroraDesk/run-linux.sh - 移除删除和检查 libSkiaSharp.so 的逻辑
    • AuroraDesk/publish-linux.ps1 - 更新启动脚本模板,移除相关逻辑
    • AuroraDesk/publish-linux.bat - 更新启动脚本模板,移除相关逻辑
  • 技术要点:
    • SkiaSharp 版本问题已通过项目文件中的显式包引用解决
    • dotnet publish 会自动处理正确的库文件复制
    • 启动脚本只需要负责启动应用程序,不需要处理库文件
  • 效果:
    • 脚本更简洁,易于维护
    • 移除了不必要的文件操作,减少潜在问题
    • 脚本专注于启动应用程序的核心功能
    • 与项目配置保持一致,不再需要手动处理库文件

修复启动脚本未复制到发布目录的问题

  • 日期: 2025年1月
  • 问题描述:
    • run-linux.sh 启动脚本没有出现在 publish\linux-x64\ 目录中
    • 即使脚本逻辑应该创建文件,但文件实际上没有被创建
    • 错误处理不够完善,创建失败时没有明确的错误提示
  • 问题原因:
    • 在创建文件之前没有确保发布目录存在
    • 错误被静默忽略(使用了 | Out-Null
    • 没有验证文件是否成功创建
  • 解决方案:
    1. 确保目录存在:
      • 在创建启动脚本之前,检查并创建发布目录(如果不存在)
      • 使用 Split-Path 获取目录路径,确保路径正确
    2. 改进错误处理:
      • 移除 | Out-Null,不再静默忽略错误
      • 检查文件是否成功创建,验证文件是否存在
      • 提供详细的错误信息和路径信息
    3. 改进批处理脚本:
      • 在创建文件之前确保 publish\linux-x64 目录存在
      • 验证文件是否成功创建
      • 提供清晰的成功/失败消息
  • 涉及文件:
    • AuroraDesk/publish-linux.ps1 - 修复 Copy-StartupScript 函数,确保目录存在并验证文件创建
    • AuroraDesk/publish-linux.bat - 修复启动脚本创建逻辑,确保目录存在并验证文件创建
  • 技术要点:
    • 使用 Split-Path -Parent 获取目录路径
    • 使用 New-Item -ItemType Directory -Force 确保目录存在
    • 创建文件后使用 Test-Path 验证文件是否存在
    • 提供详细的错误信息,包括目标路径
  • 效果:
    • 启动脚本现在会正确创建在发布目录中
    • 如果创建失败,会显示明确的错误信息
    • 改进了错误处理,不再静默失败
    • 提供了详细的成功/失败消息,包括文件路径

改进发布脚本的 SkiaSharp 库检查逻辑,避免误报错误

  • 日期: 2025年1月
  • 问题描述:
    • 发布脚本一直显示 [ERROR] Publish completed, but there are warnings or errors 错误
    • 即使发布成功,也会因为找不到 libSkiaSharp.so 而报错
    • 错误信息不够友好,没有提供足够的诊断信息
  • 解决方案:
    1. 改进文件搜索逻辑:
      • 在发布目录中递归搜索所有 libSkiaSharp.so* 文件
      • 如果文件存在于其他位置,显示所有找到的位置
      • 提供更详细的诊断信息
    2. 将错误降级为警告:
      • 如果文件不存在,不再将发布标记为失败
      • 提供可能的原因说明(应用程序可能不使用 SkiaSharp 直接,或从系统库加载等)
      • 只有在文件存在于错误位置时才返回警告状态
    3. 改进错误提示:
      • 如果文件不存在,说明这可能是正常情况
      • 提供清晰的排查步骤
      • 区分警告和错误,避免误导用户
  • 涉及文件:
    • AuroraDesk/publish-linux.ps1 - 改进 Test-SkiaSharpLibrary 函数,更智能地搜索和报告文件位置
    • AuroraDesk/publish-linux.bat - 改进库文件检查逻辑,提供更友好的错误提示
  • 技术要点:
    • 使用 Get-ChildItem -Recurse 递归搜索所有可能的位置
    • 区分文件不存在和文件位置不正确两种情况
    • 如果文件完全不存在,返回 true(不阻止发布),因为可能是正常情况
    • 如果文件存在于错误位置,返回 false(警告),但不会导致发布失败
  • 效果:
    • 解决了误报错误问题,发布成功时不再显示错误
    • 提供了更详细的诊断信息,帮助用户排查问题
    • 更友好的错误提示,区分警告和错误
    • 即使库文件不存在,也不会阻止发布流程

创建 run-linux.sh 启动脚本并改进发布脚本

  • 日期: 2025年1月
  • 问题描述:
    • 发布脚本提示需要 run-linux.sh 启动脚本,但该文件不存在
    • 用户运行发布脚本后出现错误提示,无法完成发布流程
  • 解决方案:
    1. 创建 run-linux.sh 启动脚本:
      • 创建 AuroraDesk/run-linux.sh 启动脚本
      • 脚本功能包括:
        • 检查可执行文件是否存在
        • 删除根目录的旧版本 libSkiaSharp.so(如果存在)
        • 验证 runtimes/linux-x64/native/libSkiaSharp.so 是否存在
        • 设置可执行文件权限
        • 启动应用程序
    2. 改进发布脚本:
      • 更新 publish-linux.ps1:如果源目录不存在 run-linux.sh,自动在发布目录创建
      • 更新 publish-linux.bat:如果源目录不存在 run-linux.sh,自动在发布目录创建
      • 发布脚本不再因为缺少启动脚本而报错
  • 涉及文件:
    • AuroraDesk/run-linux.sh - 新建启动脚本
    • AuroraDesk/publish-linux.ps1 - 改进启动脚本处理逻辑,自动创建脚本(如果不存在)
    • AuroraDesk/publish-linux.bat - 改进启动脚本处理逻辑,自动创建脚本(如果不存在)
  • 技术要点:
    • 启动脚本使用 exec 命令启动应用程序,确保信号正确传递
    • 脚本自动处理版本冲突问题(删除根目录的旧版本库文件)
    • 发布脚本现在更加健壮,即使源目录没有启动脚本也能正常工作
    • 启动脚本会在运行时检查必要的文件,提供清晰的错误提示
  • 效果:
    • 解决了发布脚本报错问题
    • 提供了便捷的启动脚本,用户可以直接运行 ./run-linux.sh
    • 启动脚本自动处理版本冲突和权限问题
    • 发布脚本更加健壮,自动创建必要的文件

重构 Linux 发布脚本,简化 SkiaSharp 库处理逻辑

  • 日期: 2025年1月
  • 修改原因:
    • 项目文件中已正确引用 SkiaSharp.NativeAssets.Linux 3.119.0 和 SkiaSharp.NativeAssets.Linux.NoDependencies 3.119.0
    • dotnet publish 现在会自动复制正确版本的 libSkiaSharp.so 到发布目录
    • 不再需要手动从 NuGet 包路径复制库文件
  • 重构内容:
    1. 移除手动复制逻辑:
      • 删除 Get-SkiaSharpVersion 函数(不再需要从项目文件读取版本)
      • 删除 Get-SkiaSharpSourcePath 函数(不再需要查找 NuGet 包路径)
      • 删除 Copy-SkiaSharpLibrary 函数(不再需要手动复制库文件)
      • 简化 Test-SkiaSharpLibrary 函数,仅保留验证逻辑
    2. 简化验证逻辑:
      • 仅检查 runtimes/linux-x64/native/libSkiaSharp.so 是否存在
      • 如果根目录存在旧版本的 libSkiaSharp.so,自动删除以避免版本冲突
      • 如果库文件不存在,提示检查项目文件中的包引用
    3. 更新错误提示:
      • 提示信息说明 dotnet publish 应该自动复制库文件
      • 建议检查项目文件中的包引用是否正确
  • 涉及文件:
    • AuroraDesk/publish-linux.ps1 - 移除手动复制 SkiaSharp 库的逻辑,简化脚本
    • AuroraDesk/publish-linux.bat - 移除手动复制 SkiaSharp 库的逻辑,简化脚本
  • 技术要点:
    • 当项目正确引用 SkiaSharp.NativeAssets.LinuxSkiaSharp.NativeAssets.Linux.NoDependencies 时,dotnet publish 会自动处理本地库的复制
    • 不再需要手动查找 NuGet 包路径和复制文件,简化了发布流程
    • 保留验证逻辑确保库文件正确存在,但不再需要手动复制
  • 效果:
    • 脚本代码更简洁,易于维护
    • 减少了脚本执行时间(不再需要查找和复制文件)
    • 依赖 dotnet publish 的自动处理,更符合 .NET 标准流程
    • 如果库文件缺失,会给出明确的错误提示

修复 SkiaSharp 传递依赖版本冲突问题

  • 日期: 2025年1月
  • 问题描述:
    • 项目已显式引用 SkiaSharp.NativeAssets.Linux.NoDependencies 3.119.0
    • dotnet build 构建出来的 libSkiaSharp.soC:\Users\changeself\.nuget\packages\skiasharp.nativeassets.linux.nodependencies\3.119.0\runtimes 里面的版本不一致
    • 依赖树中存在传递依赖 SkiaSharp.NativeAssets.Linux 2.88.9(旧版本),导致构建时使用了错误版本的本地库
  • 问题原因:
    • 虽然项目显式引用了 SkiaSharp.NativeAssets.Linux.NoDependencies 3.119.0
    • 但 Avalonia 或其他包传递依赖引入了 SkiaSharp.NativeAssets.Linux 2.88.9(旧版本)
    • dotnet build 时可能优先使用了传递依赖的旧版本,导致构建出来的 libSkiaSharp.so 版本不正确
    • 旧版本(2.88.9)的本地库版本是 88.1,与需要的 119.0 不兼容
  • 解决方案:
    • 在项目文件中显式引用 SkiaSharp.NativeAssets.Linux 3.119.0,覆盖传递依赖的旧版本(2.88.9)
    • 显式引用会优先于传递依赖,确保构建时使用正确版本的本地库
    • 保持 SkiaSharp.NativeAssets.Linux.NoDependencies 3.119.0 的引用,确保 Linux 发布时使用正确的本地库
  • 涉及文件:
    • AuroraDesk/AuroraDesk.csproj - 添加显式引用 SkiaSharp.NativeAssets.Linux 3.119.0
  • 技术要点:
    • 在 .NET 项目中,显式引用的包版本会覆盖传递依赖的版本
    • 当存在版本冲突时,应该显式引用正确的版本来覆盖传递依赖
    • SkiaSharp.NativeAssets.LinuxSkiaSharp.NativeAssets.Linux.NoDependencies 可以同时引用,显式引用会确保使用正确版本
    • 构建时 NuGet 会解析依赖,显式引用的版本优先级高于传递依赖
  • 测试建议:
    • 运行 dotnet restore 重新恢复包
    • 运行 dotnet build -r linux-x64 验证构建
    • 检查构建输出中的 libSkiaSharp.so 是否来自正确的 NuGet 包路径(3.119.0)
    • 验证构建出来的库文件版本与引用的包版本一致

修复 publish-linux.ps1 脚本中文乱码问题

  • 日期: 2025年1月
  • 问题描述: 脚本在英文系统环境下执行时,中文字符显示为乱码
  • 修复内容:
    1. 编码设置增强:
      • 添加 $OutputEncoding = [System.Text.Encoding]::UTF8 设置输出编码
      • 添加 chcp 65001 | Out-Null 设置控制台代码页为 UTF-8
      • 在文件读取时使用 -Encoding UTF8 参数确保正确读取中文内容
    2. 国际化处理:
      • 将所有中文提示信息替换为英文
      • 包括函数消息、错误提示、警告信息等
      • 保持脚本功能不变,仅替换显示文本
    3. 注释国际化:
      • 将代码注释从中文改为英文
      • 保持注释的清晰性和准确性
  • 涉及文件:
    • AuroraDesk/publish-linux.ps1 - 修复编码问题并将所有文本改为英文
  • 技术要点:
    • PowerShell 在不同系统环境下可能需要设置多个编码参数
    • [Console]::OutputEncoding 控制控制台输出编码
    • $OutputEncoding 控制管道输出编码
    • chcp 65001 将控制台代码页设置为 UTF-8(代码页 65001)
    • 使用 -Encoding UTF8 确保文件读取时使用 UTF-8 编码
  • 效果:
    • 脚本在英文系统环境下可以正常显示所有字符
    • 不再出现中文乱码问题
    • 编码设置更加完善,兼容性更好

重构 publish-linux.ps1 脚本

  • 日期: 2025年1月
  • 修改内容: 全面重构 publish-linux.ps1 脚本,提升代码质量和可维护性
  • 重构内容:
    1. 模块化设计:
      • 将脚本拆分为多个独立函数,每个函数负责单一职责
      • 函数包括:Invoke-DotnetCommand(执行 dotnet 命令)、Get-SkiaSharpVersion(获取版本号)、Get-SkiaSharpSourcePath(查找源文件路径)、Copy-SkiaSharpLibrary(复制库文件)、Test-SkiaSharpLibrary(检查库文件)、Copy-StartupScript(复制启动脚本)、Test-Executable(检查可执行文件)等
    2. 配置参数化:
      • 将硬编码的值提取到 $Config 哈希表中统一管理
      • 配置项包括:项目路径、运行时标识符、配置类型、输出路径、可执行文件名、启动脚本名等
      • 便于后续修改和维护
    3. 版本号自动读取:
      • 实现 Get-SkiaSharpVersion 函数,自动从项目文件 AuroraDesk.csproj 中读取 SkiaSharp 版本号
      • 使用正则表达式匹配 SkiaSharp.NativeAssets.Linux.NoDependencies 包的版本号
      • 如果读取失败,使用默认版本 3.119.0,避免硬编码版本号不匹配问题
    4. 统一日志输出:
      • 创建统一的日志函数:Write-Info(信息)、Write-Success(成功)、Write-Warning(警告)、Write-Error(错误)
      • 所有日志输出都使用统一的格式和颜色,提升可读性
    5. 错误处理改进:
      • Invoke-DotnetCommand 函数统一处理 dotnet 命令执行和错误检查
      • 支持 ContinueOnError 参数,允许某些命令失败时继续执行
      • 所有关键步骤都有错误检查和适当的错误提示
    6. 路径查找优化:
      • Get-SkiaSharpSourcePath 函数支持多个可能的 NuGet 包路径
      • 优先查找用户 NuGet 包目录($env:USERPROFILE\.nuget\packages
      • 其次查找 NUGET_PACKAGES 环境变量路径
      • 最后查找本地 packages 目录
      • 如果找不到,显示期望的完整路径,便于排查问题
    7. 代码结构优化:
      • 使用 #region#endregion 标记代码块,便于折叠和导航
      • 分为配置参数区、辅助函数区、主流程区
      • 主流程函数 Main 清晰展示脚本执行步骤
    8. 异常处理:
      • 使用 try-catch 块捕获所有异常
      • 显示详细的错误信息和堆栈跟踪
      • 确保脚本异常退出时也有适当的提示
  • 涉及文件:
    • AuroraDesk/publish-linux.ps1 - 完全重构,提升代码质量和可维护性
  • 技术要点:
    • 遵循 PowerShell 最佳实践和命名约定(函数使用动词-名词格式,如 Get-SkiaSharpVersion
    • 使用哈希表管理配置,避免硬编码
    • 函数职责单一,便于测试和维护
    • 统一的错误处理和日志输出,提升用户体验
    • 自动从项目文件读取版本号,避免版本不匹配问题
  • 效果:
    • 代码结构清晰,易于理解和维护
    • 配置参数化,便于修改和扩展
    • 版本号自动读取,避免硬编码版本不匹配
    • 统一的日志输出,提升可读性
    • 完善的错误处理,提升脚本健壮性
    • 路径查找支持多位置,提高兼容性

修复 publish-linux.bat 脚本中 SkiaSharp 版本号不匹配和强制复制问题

  • 日期: 2025年1月
  • 问题描述:
    1. 运行 publish-linux.bat 时,脚本查找的是 SkiaSharp.NativeAssets.Linux.NoDependencies 版本 3.119.1,但项目实际引用的是 3.119.0 版本
    2. 即使修复了版本号,发布目录 publish\linux-x64 中产生的 libSkiaSharp.so 仍然不正确,因为脚本在发现发布目录已存在文件时会跳过复制,导致使用了 dotnet publish 自动复制的错误版本(88.1),而不是从正确的 NuGet 包路径 C:\Users\changeself\.nuget\packages\skiasharp.nativeassets.linux.nodependencies\3.119.0\runtimes\linux-x64\native\libSkiaSharp.so 复制的正确版本(119.0)
    3. 发布后运行时出现版本不兼容错误:The version of the native libSkiaSharp library (88.1) is incompatible with this version of SkiaSharp. Supported versions of the native libSkiaSharp library are in the range [119.0, 120.0).
  • 问题原因:
    • 项目文件 AuroraDesk.csproj 中引用的是 SkiaSharp.NativeAssets.Linux.NoDependencies 版本 3.119.0
    • 正确的库文件路径应该是 C:\Users\changeself\.nuget\packages\skiasharp.nativeassets.linux.nodependencies\3.119.0\runtimes\linux-x64\native\libSkiaSharp.so
    • 脚本中所有查找路径都使用了 3.119.1 版本,导致找不到正确的库文件
    • 关键问题:脚本逻辑有缺陷,如果发布目录中已存在 libSkiaSharp.so(可能是 dotnet publish 自动复制的错误版本),脚本会跳过复制操作,直接使用错误的版本
    • 发布时可能使用了系统旧版本的 libSkiaSharp.so (88.1),而不是从 NuGet 包中复制的正确版本 (119.0)
  • 解决方案:
    1. 修复版本号:将 publish-linux.bat 脚本中所有查找 SkiaSharp 本地库的路径从 3.119.1 改为 3.119.0
    2. 强制复制逻辑
      • 在复制之前,先删除发布目录中任何已存在的 libSkiaSharp.so 文件(包括 runtimes\linux-x64\native\ 目录和根目录)
      • 移除了"如果发布目录已存在文件则跳过复制"的逻辑
      • 确保总是从正确的 NuGet 包路径强制复制,无论发布目录中是否已存在文件
      • 添加了详细的日志输出,显示源路径和目标路径
    3. 优化查找顺序
      • 优先查找用户 NuGet 包目录(最常见位置)
      • 其次查找 NUGET_PACKAGES 环境变量路径
      • 最后查找本地 packages 目录
    4. 改进错误提示:如果找不到库文件,显示期望的完整路径
  • 涉及文件:
    • AuroraDesk/publish-linux.bat - 修复版本号并改进复制逻辑,确保总是从正确的 NuGet 包路径复制
  • 技术要点:
    • 确保发布脚本中的版本号与项目文件中引用的包版本完全一致
    • SkiaSharp 3.119.0 需要本地库版本 119.0-120.0 范围
    • 重要:必须强制从正确的 NuGet 包路径复制,不能依赖 dotnet publish 自动复制的版本,因为可能包含错误的版本
    • 发布脚本必须在复制前清理已存在的文件,确保使用正确版本
    • 版本号不匹配或使用错误的库文件会导致运行时版本不兼容错误
  • 测试建议:
    • 重新运行 publish-linux.bat 脚本
    • 验证脚本输出显示从正确的 NuGet 包路径复制文件
    • 检查发布目录 publish\linux-x64\runtimes\linux-x64\native\libSkiaSharp.so 是否存在且版本正确
    • 在 Linux 系统上运行应用程序,验证不再出现版本不兼容错误

新增无线网卡信息读取功能

  • 日期: 2025年1月
  • 功能描述: 添加了读取所有无线网卡信息的功能,支持 Windows 和 Linux 平台,使用工厂模式实现平台特定逻辑
  • 实现内容:
    1. 核心层:
      • 创建 WirelessAdapterInfo 实体类,包含网卡名称、描述、MAC地址、IP地址、子网掩码、网关、DNS服务器、连接状态、信号强度、SSID、认证类型、加密类型、无线电类型、频道、网络命名空间等信息
      • 创建 IWirelessAdapterService 接口,定义获取和刷新无线网卡信息的方法
      • 创建 IWirelessAdapterServiceFactory 工厂接口,用于创建平台特定的服务实例
    2. 基础设施层:
      • 实现 WindowsWirelessAdapterService,使用 WMI 和 netsh 命令获取 Windows 平台的无线网卡信息
      • 实现 LinuxWirelessAdapterService,使用多种方法检测无线网卡:
        • 方法1: 使用 iw dev 命令获取所有无线接口(最可靠)
        • 方法2: 使用 ip link show type wifi 命令获取无线接口
        • 方法3: 检查 /sys/class/net 目录,查找有 wireless 子目录的接口
        • 方法4: 回退到 NetworkInterface 过滤(按类型和名称)
      • 实现 WirelessAdapterServiceFactory,根据运行时平台自动选择对应的服务实现
      • Linux 实现支持网络命名空间检测,包括:
        • 检查当前进程的网络命名空间(通过 /proc/self/ns/net
        • 通过 ip link 命令查询接口的命名空间
        • /sys/class/net/{interface}/netns 文件读取命名空间信息
        • 通过 ip netns list 将命名空间 ID 转换为名称
        • 检测容器环境(Docker、Kubernetes、LXC)并显示容器命名空间信息
    3. 表示层:
      • 创建 WirelessAdapterPageViewModel,管理网卡列表、加载和刷新逻辑
      • 创建 WirelessAdapterPageView,展示网卡信息的现代化界面,包括:
        • 顶部统计卡片(网卡总数、已连接数量、状态信息)
        • 刷新和重新加载按钮
        • 详细的网卡信息列表,包括基本网络信息、无线网络信息、网络命名空间(Linux)等
      • 添加转换器:BoolToBrushConverter(连接状态颜色)、StringToVisibilityConverter(字符串可见性)、IntToVisibilityConverter(整数可见性)
    4. 服务注册:
      • Infrastructure.Extensions.ServiceCollectionExtensions 中注册 IWirelessAdapterServiceFactory
      • Presentation.Extensions.ServiceCollectionExtensions 中注册 WirelessAdapterPageViewModel
      • PageViewModelFactory 中添加 CreateWirelessAdapterPageViewModel 方法
    5. 导航集成:
      • NavigationService 中添加"无线网卡信息"导航项,使用 IconType.Signal 图标
  • 涉及文件:
    • AuroraDesk.Core/Entities/WirelessAdapterInfo.cs - 无线网卡信息实体
    • AuroraDesk.Core/Interfaces/IWirelessAdapterService.cs - 服务接口
    • AuroraDesk.Core/Interfaces/IWirelessAdapterServiceFactory.cs - 工厂接口
    • AuroraDesk.Infrastructure/Services/WindowsWirelessAdapterService.cs - Windows 实现
    • AuroraDesk.Infrastructure/Services/LinuxWirelessAdapterService.cs - Linux 实现(支持网络命名空间)
    • AuroraDesk.Infrastructure/Services/WirelessAdapterServiceFactory.cs - 工厂实现
    • AuroraDesk.Presentation/ViewModels/Pages/WirelessAdapterPageViewModel.cs - ViewModel
    • AuroraDesk.Presentation/Views/Pages/WirelessAdapterPageView.axaml - 视图 XAML
    • AuroraDesk.Presentation/Views/Pages/WirelessAdapterPageView.axaml.cs - 视图代码后台
    • AuroraDesk.Presentation/Converters/StringConverters.cs - 新增转换器
    • AuroraDesk.Infrastructure/Extensions/ServiceCollectionExtensions.cs - 服务注册
    • AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs - ViewModel 注册
    • AuroraDesk.Presentation/Services/PageViewModelFactory.cs - 页面工厂
    • AuroraDesk.Infrastructure/Services/NavigationService.cs - 导航服务
    • AuroraDesk.Infrastructure/AuroraDesk.Infrastructure.csproj - 添加 System.Management 包
  • 技术特点:
    • 使用工厂模式实现平台特定逻辑,符合开闭原则
    • Linux 实现支持网络命名空间检测,适用于容器化环境
    • 异步加载和刷新,不阻塞 UI 线程
    • 现代化的界面设计,信息展示清晰
    • 支持 Windows 和 Linux 双平台
  • 效果:
    • 可以在导航栏中访问"无线网卡信息"页面
    • 自动检测并显示所有无线网卡信息
    • Linux 环境下使用多种方法检测无线网卡,提高检测成功率
    • Linux 环境下自动检测并显示网络命名空间信息
    • 支持手动刷新和重新加载网卡信息
  • 后续优化:
    • 修复了 Linux 环境下检测不到无线网卡的问题,改用多种检测方法(iw devip link show type wifi/sys/class/net 检查)
    • 添加了详细的日志输出,便于调试和排查问题
    • 重要优化:支持跨网络命名空间检测
      • 重构了 LinuxWirelessAdapterService,支持检测所有网络命名空间中的无线网卡
      • 使用 ip netns list 获取所有命名空间列表
      • 在每个命名空间中使用 ip netns exec <namespace> iw dev 检测无线接口
      • 对于其他命名空间中的接口,使用 ip netns exec <namespace> ip addr show 获取接口信息
      • 所有 iwiwconfig 命令都支持通过 ip netns exec 在指定命名空间中执行
      • 界面中会显示每个无线网卡所属的网络命名空间(默认命名空间显示为 "default")
      • 解决了网络命名空间隔离环境下无法检测到无线网卡的问题

修复 BreathePageView 页面切换闪退问题

  • 日期: 2025年1月
  • 问题: 第一次进入 BreathePageView 没问题,导航到其他页面后再切换回来时出现 System.ExecutionEngineException 闪退(HResult: -2146233082)
  • 问题分析:
    • 生命周期管理缺失: BreathePageView 没有正确处理页面激活/停用生命周期,导致 Lottie 控件资源管理混乱
    • XAML 绑定时机问题: 页面重新激活时,XAML 绑定立即更新 Path 属性,但 Lottie 控件的资源可能还未完全清理
    • 资源释放冲突: 当页面重新加载时,控件试图访问已经被释放或正在释放的 Skia 底层资源,导致 ExecutionEngineException
    • 控件实例复用: 同一个 Lottie 控件实例在页面切换时被重复使用,导致资源状态混乱
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/BreathePageView.axaml (使用 ContentControl 作为容器)
    • AuroraDesk.Presentation/Views/Pages/BreathePageView.axaml.cs (动态创建和销毁 Lottie 控件)
  • 主要修复:
    • 条件渲染: 使用 ContentControl 作为容器,不在 XAML 中直接放置 Lottie 控件,改为在代码后台动态创建
    • 动态创建控件: 在页面激活时(WhenActivated)创建全新的 Lottie 控件实例,确保每次都是干净的状态
    • 完全销毁控件: 在页面停用时,通过设置 ContentControl.Content = null 完全移除控件,触发控件的 OnUnloaded 和资源清理
    • 生命周期管理: 使用 WhenActivated 管理页面生命周期,确保控件在正确的时机创建和销毁
    • 订阅管理: 正确管理 RepeatCountAnimationPath 的订阅,在停用时自动清理
    • 线程安全: 所有 UI 操作都通过 Dispatcher.UIThread.Post 在 UI 线程上执行
    • 异常处理: 添加 try-catch 捕获所有异常,避免崩溃
  • 技术细节:
    • 在 XAML 中使用 <ContentControl x:Name="LottieContainer" /> 作为容器
    • CreateLottieControl 方法中动态创建新的 Lottie 控件实例
    • 设置控件的初始属性(RepeatCount、Stretch、对齐方式等)
    • 订阅 ViewModel.RepeatCountViewModel.AnimationPath 变化
    • 将控件添加到 ContentControl.Content,触发加载和初始化
    • DestroyLottieControl 中设置 Content = null,触发控件的卸载和资源清理
    • 所有订阅都添加到 CompositeDisposable,确保在停用时自动清理
  • 效果:
    • 页面切换正常: 每次页面激活时创建全新的控件实例,避免了资源冲突
    • 资源管理正确: 通过完全移除控件,确保 Skia 资源被正确释放
    • 异常安全: 即使出现异常,也不会导致应用崩溃,只会记录日志
    • 彻底解决: 通过动态创建和销毁控件,从根本上避免了 ExecutionEngineException

新增文件浏览页面

  • 日期: 2025年11月14日
  • 调整内容:
    1. 新增 FileExplorerPageViewModelFileExplorerPageView,实现“上方目录选择 + 下方左右布局”,左侧统计文件数量并展示可展开的文件树,右侧通过 AvaloniaEdit 预览内容(xmlns:avaloniaEdit="clr-namespace:AvaloniaEdit;assembly=AvaloniaEdit")。
    2. 将页面注册到 DI 与导航:ServiceCollectionExtensionsPageViewModelFactoryNavigationService 新增 file-explorer 项,侧边菜单可直接进入“文件浏览”工具。
    3. 为顶部容器设置三列 Grid.Column,分别承载说明文本、目录路径文本框与操作按钮,避免控件堆叠;文件树标题/描述分别占 Grid.Row="0/1",并改用 TreeView 展示目录层级,点击节点即可预览文件。
    4. 右侧预览区加入“语法高亮”下拉框,绑定新属性 SelectedHighlightLanguage;支持自动按扩展名检测(C#/JSON/YAML/Markdown 等),并通过 TextMateHelperTextEditor 中切换语言。
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/FileExplorerPageViewModel.cs
    • AuroraDesk.Presentation/Views/Pages/FileExplorerPageView.axaml
    • AuroraDesk.Presentation/Views/Pages/FileExplorerPageView.axaml.cs
    • AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs
    • AuroraDesk.Presentation/Services/PageViewModelFactory.cs
    • AuroraDesk.Infrastructure/Services/NavigationService.cs
  • 效果:
    • 目录选择 + 列表 + AvaloniaEdit 预览一屏完成,方便快速阅读文件。
    • 顶部与列表区域不再发生文字重合,控件分区清晰。
    • 导航菜单出现“文件浏览”入口,可随时切换。

文件浏览页面新增搜索框

  • 日期: 2025年11月14日
  • 调整内容:
    1. FileExplorerPageViewModel 新增 SearchQueryFilteredTreeItems 以及节点克隆过滤逻辑,根据关键字实时筛选文件树。
    2. LoadDirectoryAsync 结束后自动同步筛选结果,保持计数信息与过滤列表一致。
    3. FileExplorerPageView 左侧文件树上方加入搜索框,输入内容时立即按名称匹配文件或文件夹。
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/FileExplorerPageViewModel.cs
    • AuroraDesk.Presentation/Views/Pages/FileExplorerPageView.axaml
  • 效果:
    • 文件树可按关键字快速定位目标,提升大型目录下的浏览效率。
    • 过滤结果保持原有层级结构,仅展示匹配节点及其父级上下文。

调整 breathe 系列动画画布宽度

  • 日期: 2025年11月14日
  • 调整内容:
    1. breathe.jsonbreatheV2.json 的合成宽度从 680 提升至 960,并把两层文字图层的 p.x 调整为 480(新宽度的一半),留足左右余量。
    2. 保持高度和缩放不变,仅扩充画布以容纳霓虹外发光区域。
  • 涉及文件:
    • AuroraDesk.Presentation/Resources/Animations/breathe.json
    • AuroraDesk.Presentation/Resources/Animations/breatheV2.json
  • 效果:
    • “AVALONIA” 与 “WELCOME BACK” 再无左右被裁剪的问题,光晕完整可见。

修复 breathe 动画字体缺失导致崩溃

  • 日期: 2025年11月14日
  • 调整内容:
    1. breathe.jsonbreatheV2.json 的字体信息由 STHupo 改为应用内置的 Inter,避免依赖系统是否安装华文琥珀字体。
    2. 同步更新两段文本样式的 f 字段,并把填充色改为高饱和蓝色,保证浅色背景下也能明显看到文字。
    3. 修复 breathe.json 中 Drop Shadow 参数名出现乱码导致 JSON 无效的问题,改用英文字符串(Opacity/Softness/Shadow Only)。
  • 涉及文件:
    • AuroraDesk.Presentation/Resources/Animations/breathe.json
    • AuroraDesk.Presentation/Resources/Animations/breatheV2.json
  • 效果:
    • breathe.json/breatheV2.json 在任意设备上都能立即显示文本内容,不再出现空白。
    • Tab 之间切换不再触发 System.ExecutionEngineException,Lottie 控件释放/重建稳定。

重构呼吸页面并解除 Lottie 裁剪

  • 日期: 2025年11月14日
  • 调整内容:
    1. 重新组织 BreathePageView 布局:顶部保留标题区,下方改为“左侧控制面板 + 右侧预览卡片”的两列结构,加入动画资源信息卡、播放设置卡与更醒目的 V3 提示。
    2. 右侧预览区采用深色画布 + Viewbox 自适应缩放,整体卡片使用大圆角与更充足的留白,视觉风格与其他页面保持一致。
    3. 为动画容器和 lottie:Lottie 控件设置 ClipToBounds="False",并嵌入 Viewbox,确保 breatheV2.json 中带有负偏移的霓虹光晕不会被边框裁剪。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/BreathePageView.axaml
  • 效果:
    • 呼吸页面的基础信息、动画选择与播放状态分区明确,界面更现代。
    • Lottie 动画可完整展示 “WELCOME BACK” 文本与外扩光效,彻底消除左侧被截断的问题。

优化呼吸动画实时预览卡片

  • 日期: 2025年11月14日
  • 调整内容:
    1. BreathePageView 右侧预览区域由深色背景改为浅色渐变卡片,采用双层圆角 + 柔和描边,与整页风格保持一致。
    2. 保留 Viewbox 自适应缩放并添加提示语与所选动画名称徽章,确保 breathe.json / breatheV2.json 等不同画布能在统一边界内完整显示。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/BreathePageView.axaml
  • 效果:
    • 预览卡片视觉更轻盈,与左侧控制面板色调统一。
    • 动画得到充分留白,宽幅文本不再与黑背景冲突。

调整 TCP 客户端消息输入位置

  • 日期: 2025年11月14日
  • 调整内容:
    1. TcpClientPageView 中的消息输入框和发送按钮移至会话详情底部的独立卡片,避免与“已发送消息”列表混排。
    2. 保留原有列表虚拟化结构,接收消息区域布局不受影响。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/TcpClientPageView.axaml
  • 效果:
    • 发送输入区位置更符合用户预期,界面层级更清晰。
    • 接收消息容器与统计展示保持原样,交互逻辑未受影响。

调整呼吸动画展示区域铺满

  • 日期: 2025年11月14日
  • 调整内容:
    1. BreathePageView 动画容器的对齐方式改为水平/垂直拉伸,允许边框随父容器铺满。
    2. 移除 Lottie 控件的固定宽高,改用拉伸对齐以按可用空间呈现动画。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/BreathePageView.axaml
  • 效果:
    • 呼吸动画在内容区域内自动拉伸显示,视觉更协调。
    • 保持圆角与边框效果,未引入布局断裂。

修复呼吸动画首字母被裁剪

  • 日期: 2025年11月14日
  • 调整内容:
    1. 将预览区域 ViewboxMaxWidth 提升至 1200,与最新 breathe.json 画布一致。
    2. 移除 Viewbox 四周 36px 边距,确保动画可获得完整宽度。
    3. 同步扩充 breathe.json 合成宽度并将文字位置改为 x=600,彻底消除首字母被裁剪的问题。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/BreathePageView.axaml
    • AuroraDesk.Presentation/Resources/Animations/breathe.json
  • 效果:
    • “AVALONIA” 文本首字母不再被裁剪,光晕完整显示。
    • 其它呼吸动画同样可利用更宽画布,避免边缘截断。

呼吸动画资源信息支持切换

  • 日期: 2025年11月14日
  • 调整内容:
    1. 将动画资源说明文本改为绑定 AnimationPath,通过 StringFormat 展示当前路径。
    2. 当页面切换不同动画资源时,文本会实时更新,无需修改 XAML。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/BreathePageView.axaml
  • 效果:
    • 动画资源路径展示可随绑定变化自动刷新。
    • 便于后续通过 ViewModel 切换不同动画文件。

呼吸动画页面支持多个资源切换

  • 日期: 2025年11月14日
  • 调整内容:
    1. BreathePageViewModel 新增动画资源列表与所选项绑定,预置 breathe.jsoncapability.json
    2. BreathePageView 中加入下拉选择控件,绑定至 ViewModel,选项变更时自动更新动画路径。
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/BreathePageViewModel.cs
    • AuroraDesk.Presentation/Views/Pages/BreathePageView.axaml
  • 效果:
    • 页面可快速切换不同 Lottie 资源,无需修改代码。
    • 资源说明文本与动画展示同步更新,体验一致。

呼吸动画替换 capability 资源

  • 日期: 2025年11月14日
  • 调整内容:
    1. breatheV2.json 拷贝至 Resources/Animations,并在 BreathePageViewModel 中以“呼吸引导 V2”形式加入动画列表。
    2. 移除无效的 capability.json 选项及对应文件,确保用户只看到可播放的 Lottie 资源。
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/BreathePageViewModel.cs
    • AuroraDesk.Presentation/Resources/Animations/breatheV2.json
    • AuroraDesk.Presentation/Resources/Animations/capability.json(已删除)
    • capability.json(已删除)
  • 效果:
    • “能力演示”选项改为可用的 V2 动画,切换后立即生效。
    • 避免加载配置文件导致 Lottie 控件空白的问题。

优化 breatheV2 “WELCOME BACK” 动画

  • 日期: 2025年11月14日
  • 调整内容:
    1. breatheV2.json 的文本更新为 “WELCOME BACK” 单行霓虹效果,并应用蓝青色描边与荧光色填充,突出“欢迎回来”主题。
    2. 调整双层投影的颜色、距离与柔和度,呈现更科幻的霓虹发光效果。
    3. 多次迭代后采用左移 30px + 深度压缩布局(字号 95、缩放 60%、行距 120、轻微负字距),确保 680×280 画布内完整呈现、左右留白均匀。
  • 涉及文件:
    • AuroraDesk.Presentation/Resources/Animations/breatheV2.json
  • 效果:
    • 新动画展现出更具科技感且完整的欢迎视觉,左右留白均衡。
    • Lottie 结构保持不变,仍可在 BreathePageView 中稳定循环播放。

缩放 breathe.json 避免截断

  • 日期: 2025年11月14日
  • 调整内容:
    1. breathe.json 两层文字的缩放从 100% 降至 85%,字号从 192 调整为 150,并把行距降至 180。
    2. 文本对齐方式改为居中(j=2),确保 “AVALONIA” 在 680×280 画布内水平居中展示,不再出现左右裁切。
  • 涉及文件:
    • AuroraDesk.Presentation/Resources/Animations/breathe.json
  • 效果:
    • 默认动画与 V2/V3 一样能完整显示,且视觉集中在容器正中。
    • Lottie 文件结构保持兼容,仍可在 Breathe 页面中循环播放。

新增 breathe_V3 科技律动动画

  • 日期: 2025年11月14日
  • 调整内容:
    1. 解除 breathe_V3.json 只读属性并纳入 Resources/Animations,供页面加载。
    2. BreathePageViewModel 的动画列表中新增“科技律动 V3”选项,路径指向 breathe_V3.json
    3. BreathePageView.axaml 中补充提示卡片,引导用户选择最新动画资源。
  • 涉及文件:
    • AuroraDesk.Presentation/Resources/Animations/breathe_V3.json
    • AuroraDesk.Presentation/ViewModels/Pages/BreathePageViewModel.cs
    • AuroraDesk.Presentation/Views/Pages/BreathePageView.axaml
  • 效果:
    • 主页面可直接切换到 V3 动画,提示区域也醒目展示新资源信息。
    • 所有动画选项均为有效 Lottie 文件,避免空白加载。

调整动画显示尺寸避免内容被裁剪

  • 日期: 2025年11月14日
  • 调整内容:
    1. 将呼吸动画控件对齐方式改为居中,不再随容器拉伸。
    2. 为 Lottie 控件增加最大宽高(680×280),保证文本在放大时不被裁剪。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/BreathePageView.axaml
  • 效果:
    • 动画文字保持完整可见,避免铺满后出现截断。
    • 仍然维持适度缩放,居中展示更清晰。

新增 TCP 客户端多会话视图

  • 日期: 2025年11月13日
  • 调整内容:
    1. 新建 TcpClientPageView XAML,延续 UDP 页面卡片化风格,新增顶部全局统计、左侧会话列表和右侧详情区,支持多会话并列管理。
    2. 详情区围绕选中会话提供连接配置、帧类型/CRC 开关、发送与接收双栏布局,并引入自动置底、重连入口等交互元素。
    3. 实现 TcpClientPageViewModelTcpClientSessionViewModel,遵循「长度 + 类型 + payload (+ CRC32)」协议构帧,支持多会话异步连接、发送、接收与 CRC 校验。
    4. 重写页面代码后台为强类型订阅,按选中会话自动定位到最新消息,同时更新导航、依赖注入以开放 TCP 客户端 菜单。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/TcpClientPageView.axaml
    • AuroraDesk.Presentation/Views/Pages/TcpClientPageView.axaml.cs
    • AuroraDesk.Presentation/ViewModels/Pages/TcpClientPageViewModel.cs
    • AuroraDesk.Presentation/ViewModels/Pages/TcpClientSessionViewModel.cs
    • AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs
    • AuroraDesk.Presentation/Services/PageViewModelFactory.cs
    • AuroraDesk.Infrastructure/Services/NavigationService.cs
  • 效果:
    • 一次性落地 TCP 多会话能力,自动完成协议封包、CRC 追加/校验与回显。
    • UI 与逻辑均已就绪,可直接在导航中创建/切换会话并查看实时收发记录。

为 UDP 客户端接收消息添加自动滚动控制

  • 日期: 2025年11月10日
  • 调整内容:
    1. UdpClientPageView 接收消息标题栏新增“滚动到底部”复选框,默认开启。
    2. 引入 IsAutoScrollToBottom 属性控制是否在收到新消息时自动将滚动条置底。
    3. 在视图代码后台监听消息集合变化,根据复选框状态自动滚动到底部。
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/UdpClientPageViewModel.cs
    • AuroraDesk.Presentation/Views/Pages/UdpClientPageView.axaml
    • AuroraDesk.Presentation/Views/Pages/UdpClientPageView.axaml.cs
  • 效果:
    • 用户可按需开启/关闭自动滚动,防止查看历史记录时被打断。
    • 默认保持自动滚动,确保实时看到最新消息。
  • 日期: 2025年11月11日
  • 调整内容:
    1. 在核心层新增 PlinkSessionOptions/Info/Message 等数据模型与 IPlinkSessionService 接口,抽象 SSH (plink) 会话的启动、消息流与状态订阅。
    2. 基础设施层落地 PlinkSessionService,通过并发字典管理多会话生命周期,异步泵送 stdout/stderr,支持实时消息、错误提示与安全退出。
    3. 表示层新增 PlinkPageViewModelPlinkSessionItemViewModel 以及对应视图 PlinkPageView,实现会话表单创建、列表管理、消息实时显示与指令输入。
    4. 新建会话交互重构:基础信息采用两列卡片布局,认证方式新增密码/私钥单选切换并按模式启用控件;高级设置收纳进 Expander,默认界面更聚焦。
    5. 将 “当前会话” 列表移至右侧独立列,保留中间区域用于实时消息与指令输入,整体信息分区更清晰。
    6. 新增 PlinkMessageBackgroundConverter、空值反转转换器等 UI 工具,并完善命令/调度逻辑(Dispatcher.UIThread)确保线程安全。
    7. 更新 DI 容器与导航(ServiceCollectionExtensions、PageViewModelFactory、NavigationService),在侧边栏新增 “SSH 工具 > Plink 会话” 菜单。
  • 涉及文件:
    • AuroraDesk.Core/Entities/PlinkSessionModels.cs
    • AuroraDesk.Core/Interfaces/IPlinkSessionService.cs
    • AuroraDesk.Infrastructure/Services/PlinkSessionService.cs
    • AuroraDesk.Infrastructure/Extensions/ServiceCollectionExtensions.cs
    • AuroraDesk.Infrastructure/Services/NavigationService.cs
    • AuroraDesk.Presentation/ViewModels/Pages/PlinkPageViewModel.cs
    • AuroraDesk.Presentation/Views/Pages/PlinkPageView.axaml
    • AuroraDesk.Presentation/Views/Pages/PlinkPageView.axaml.cs
    • AuroraDesk.Presentation/Converters/PlinkMessageConverters.cs
    • AuroraDesk.Presentation/Converters/StringConverters.cs
    • AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs
    • AuroraDesk.Presentation/Services/PageViewModelFactory.cs
  • 效果:
    • 支持创建/管理任意数量的 Plink 会话,状态与消息实时响应。
    • 列表与消息区具备现代化界面与语义化颜色,易于运维排查。
    • 导航栏新增 SSH 工具分类,功能入口清晰可见。
  • 日期: 2025年11月11日
  • 调整内容:
    1. PlinkPageView 基本信息区域的两列网格补充 RowDefinition 配置,确保上下字段按照行排列。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/PlinkPageView.axaml
  • 效果:
    • “主机/端口”“用户名/显示名称” 字段分行显示,避免横向挤压与重叠。
  • 日期: 2025年11月11日
  • 调整内容:
    1. PlinkPageView 顶部表单改为 Expander + Grid 结构,复用 SshPageView 的列/行布局与标题样式,保持 MaxHeight=240
    2. 单行展示主机、端口、用户名、显示名称;认证行整合密码与附加参数;私钥路径与 Plink 路径并列于第三行。
    3. 统一按钮与状态提示的并排布局,将“自动接受主机密钥”复选框与操作行同行展示,使交互逻辑与 SSH 页面保持一致。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/PlinkPageView.axaml
  • 效果:
    • Plink 与 SSH 页面在视觉与交互上保持一致,用户迁移成本低。
    • 关键字段一屏可见,表单高度受控且更易填写。
  • 日期: 2025年11月11日
  • 调整内容:
    1. 将 Plink 页面顶级容器改为上下布局,上方保留表单卡片,下方按 320,16,* 分栏重排列表与详情,复用 SSH 页面的结构。
    2. 调整表单内部栅格,延续“标签+输入”组合列宽,同时保留 Plink 特有的附加参数、可执行路径与自动接受主机密钥选项。
    3. 将会话列表置于左侧卡片,保持标题徽章与操作按钮样式,与右侧详情区形成与 SSH 页面一致的视觉分区。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/PlinkPageView.axaml
  • 效果:
    • Plink 与 SSH 页面拥有统一的布局骨架,用户切换工具时体验一致。
    • 表单、列表与消息区排布协调,整体视觉层级更清晰。
  • 日期: 2025年11月11日
  • 调整内容:
    1. 将 “新建 Plink 会话” 卡片的 MaxHeight 从 240 提升至 300,确保附加参数与 Plink 路径等字段在折叠头展开时全部可见。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/PlinkPageView.axaml
  • 效果:
    • 表单展开时不再裁剪底部内容,填写体验更顺畅。
  • 日期: 2025年11月11日
  • 调整内容:
    1. PlinkPageViewModel 在创建会话后等待短暂握手窗口,若状态回落为 Error/Disconnected 则移除并提示失败原因。
    2. 捕获异常路径提前释放创建中的 ViewModel 资源,防止潜在泄漏。
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/PlinkPageViewModel.cs
  • 效果:
    • “创建并连接会话” 在连接失败时不再向“当前会话”列表添加无效项,并显示详细错误信息。

新增独立 SSH 会话管理页面

  • 日期: 2025年11月11日
  • 调整内容:
    1. 核心层新增 SshSessionOptions/Info/Message 数据模型与 ISshSessionService 接口,定义多会话 SSH 能力。
    2. 基础设施层实现 SshSessionService,基于系统 ssh 可执行文件支持多会话、自动响应密码/私钥口令提示与日志推送。
    3. 表示层新增 SshPageViewModelSshSessionItemViewModelSshPageView,复用三列布局展示表单、消息区与会话列表。
    4. 更新 DI、导航与页面工厂,为 SSH 工具分组增加“SSH 会话”入口。
  • 涉及文件:
    • AuroraDesk.Core/Entities/SshSessionModels.cs
    • AuroraDesk.Core/Interfaces/ISshSessionService.cs
    • AuroraDesk.Infrastructure/Services/SshSessionService.cs
    • AuroraDesk.Infrastructure/Extensions/ServiceCollectionExtensions.cs
    • AuroraDesk.Infrastructure/Services/NavigationService.cs
    • AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs
    • AuroraDesk.Presentation/Services/PageViewModelFactory.cs
    • AuroraDesk.Presentation/ViewModels/Pages/SshPageViewModel.cs
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml.cs
  • 效果:
    • 新页面独立管理基于 ssh.exe 的实时会话,支持多客户端并行、消息推送与命令发送。
    • 表单支持密码或私钥两种认证方式,可配置首选 Shell、自动接受主机密钥与自定义执行路径。

重构 SSH 会话页面布局

  • 日期: 2025年11月11日
  • 调整内容:
    1. SshPageView 顶层布局调整为上下结构,上部保留新建会话表单,下部重排为左右分栏呈现客户端列表与消息详情,并将下部区域权重设为 2/3。
    2. 移除“高级设置”折叠区,并将表单放入可折叠的 Expander,默认展开,提升页面聚焦度与可折叠性。
    3. 重新组织列表与消息区的边框、提示文案,左侧列表与右侧内容的关联关系更直观。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 新建表单置顶集中,填写流程更顺滑。
    • 下方左右分栏一眼区分“客户端”与“收发内容”,定位操作更轻松。
    • 页面整体留白与层级更平衡,视觉更简洁。

紧凑化 SSH 表单布局

  • 日期: 2025年11月11日
  • 调整内容:
    1. 将“基本信息”“认证方式”分列排布,使用 Grid 横向并列呈现表单内容,显著降低整体高度。
    2. 认证区域改为双列网格,密码与私钥口令同排展示,私钥路径独占一行,减少垂直空间。
    3. 调整创建按钮与状态提示为整行布局,保持与新网格结构对齐。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 表单高度收紧,核心字段在一屏内即可完成填写。
    • 密码/私钥配置分区更紧凑,阅读路径清晰。
    • 按钮与状态信息对齐整齐,交互区块不再显得松散。

让 SSH 表单控件铺满列宽

  • 日期: 2025年11月11日
  • 调整内容:
    1. 为表单中 StackPanel 与输入控件补充 HorizontalAlignment="Stretch" 设置,确保列宽空间被完整利用。
    2. 端口 NumericUpDown、密码/口令输入框与私钥路径等控件均支持随宽度扩展,避免出现控件宽度不足。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 每行控件自然铺满当前列,视觉更加平衡。
    • 多列布局在宽屏下能充分展示信息,减少空白区域。

SSH 表单折叠头部拉伸对齐

  • 日期: 2025年11月11日
  • 调整内容:
    1. 为“新建 SSH 会话” Expander 设置 HorizontalAlignment="Stretch" 与自定义 HeaderTemplate,复制 UdpClientPageView 中“连接配置”折叠栏的铺满效果。
    2. 标题行增加统一边距与 18px 图标,使折叠状态仍占满整行,避免右侧空白。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 折叠状态下标题横向拉满,页面风格与其他网络工具保持一致。
    • 点击区域更大,操作体验更接近 UDP 页面。

SSH 基本信息单行布局

  • 日期: 2025年11月11日
  • 调整内容:
    1. 将基本信息四项(主机、端口、用户名、显示名称)改为单行网格排布,标签与输入框横向组合。
    2. 认证区域保持折叠内第二行,采用标签+输入框单行布局,私钥路径独占第二行。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 基本信息在一行内填写完成,视觉更整洁。
    • 认证信息紧随其后,占用空间更紧凑统一。

压缩 SSH 新建表单高度

  • 日期: 2025年11月11日
  • 调整内容:
    1. 降低折叠区上下 MarginPadding,将输入控件内边距调整为 6x4 并收紧列距/行距,使表单整体高度更低。
    2. 调整操作按钮与状态提示的内边距,保持视觉统一的同时减少额外空白。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • “新建 SSH 会话”卡片高度显著降低,重要信息仍然清晰可读。
    • 控件间距统一更紧凑,页面首屏可展示更多内容。

精简认证方式行占用

  • 日期: 2025年11月11日
  • 调整内容:
    1. 移除“认证类型”标签,让密码/私钥切换单元与同排输入框在一行内对齐。
    2. 私钥路径行的列跨度随之调整,保持布局紧凑。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 认证区域减少额外标签占位,视觉上更加简洁。
    • 相关输入控件仍保持清晰的分隔与可读性。

移除认证方式标题占位

  • 日期: 2025年11月11日
  • 调整内容:
    1. 删除折叠内“认证方式”标题 TextBlock,直接以网格呈现,让整个版块更紧凑。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 认证区域高度进一步降低,避免重复标题造成空白。
  • 日期: 2025年11月11日
  • 调整内容:
    1. 移除多余的 </StackPanel>,恢复 PlinkPageView 顶部 Border 正确的标签匹配,保证 XAML 可解析。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/PlinkPageView.axaml
  • 效果:
    • dotnet build 不再因 XAML 标签错配而失败。

压缩 SSH 表单高度至 240

  • 日期: 2025年11月11日
  • 调整内容:
    1. 将“新建 SSH 会话”卡片改为三行网格:基础信息行、认证行、操作行,移除多余 StackPanel,设置 MaxHeight="240"
    2. 基础信息与认证字段采用紧凑列分布,按钮与状态提示并列放置,收紧控件内边距至 6x4/10x6
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 表单高度控制在 240 内,布局仍保持清晰。
    • 关键信息一屏可见,交互流程更顺畅。

合并 SSH 表单折叠

  • 日期: 2025年11月11日
  • 调整内容:
    1. 将“基础信息”“认证详情”重新合并为单个 Expander,内部分 5 行 Grid 依次呈现主机/端口/用户名/显示名称、认证方式、密码/口令、私钥路径及操作行。
    2. 保留 MaxHeight=240 约束,按钮与状态提示继续并排,整体高度紧凑。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 表单信息在同一折叠中连续填写,交互路径更顺滑。
    • 保持原有高度限制与紧凑视觉布局。

优化 SSH 表单列对齐

  • 日期: 2025年11月11日
  • 调整内容:
    1. 重新划分首两行网格列宽,使“主机/端口”“用户名/显示名称”分别同行展示,控件宽度统一。
    2. 认证行将方式切换、密码与私钥口令合并在同一 Grid 中,减少垂直高度并保持对齐。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 表单字段排布整齐、信息不再拥挤。
    • 关键信息在压缩高度下仍能完整显示。

SSH 表单卡片双列化

  • 日期: 2025年11月11日
  • 调整内容:
    1. 将折叠内部布局重构为两列栅格,左列承载主机/端口与用户名/显示名称,右列展示认证方式,保证左右留白均衡。
    2. 密码、私钥口令与私钥路径拆分为独立栈面板,并在底部统一按钮+状态提示排版,整体间距统一为 12~16px。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 表单视觉更加平衡,不再出现某段拥挤某段留白的情况。
    • 字段顺序清晰,所有输入内容均在折叠高度限制内完整可见。

SSH 表单统一四列排布

  • 日期: 2025年11月11日
  • 调整内容:
    1. 将主机/端口/用户名/显示名称对齐于同一行四列,认证方式、密码、私钥口令、私钥路径也按四列并排显示,整体改为 StackPanel + Grid 组合。
    2. 減少重复容器,按钮与状态信息保留底部一行,视觉更紧凑、字段一目了然。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 单行即展示全部核心字段,左右留白更均衡。
    • 高度仍控制在 240 之内,信息布局清晰。

SSH 表单标签/控件对齐

  • 日期: 2025年11月11日
  • 调整内容:
    1. 改为单个 Grid,通过 Auto,* 成对列定义实现“标签+控件”组合的四列排布,并为间隔列设置固定空间,防止重叠。
    2. 私钥路径独占全宽行,按钮与状态信息置于第四行独立 Grid,整体间距统一。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 四列布局真正对齐,输入框不再拥挤或重合。
    • 折叠高度依旧受控,字段读取更加直观。

SSH 操作栏并入私钥行

  • 日期: 2025年11月11日
  • 调整内容:
    1. 将按钮和状态提示移入私钥路径同行,采用三列布局(按钮、间隔、状态)保持横向紧凑。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 操作区与路径配置在同一视觉行,节省垂直空间。
    • 状态消息仍具备充分宽度并随文本自动换行。

阻止连接失败的 SSH 会话出现在列表

  • 日期: 2025年11月11日
  • 调整内容:
    1. SshPageViewModel 在调用 StartSessionAsync 后等待状态首次变为 Connected/Disconnected/Error,仅在成功连通后才加入 _sessions
    2. 失败或超时直接获取最新错误消息并提示,同时释放临时 ViewModel,避免列表残留。
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/SshPageViewModel.cs
  • 效果:
    • SSH 连接失败不会再出现在左侧客户端列表,状态提示更准确。
    • 避免短暂失败会话占用资源。

SSH 会话增加握手验证

  • 日期: 2025年11月11日
  • 调整内容:
    1. SshPageViewModel 在检测首个非 Connecting 状态后发送 echo __aurora_ssh_handshake__,若 5 秒内未收到响应即判定失败并提示。
    2. 成功握手后再等 0.5 秒确认状态稳定,再将会话加入列表。
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/SshPageViewModel.cs
  • 效果:
    • 即便口令错误或远端拒绝交互,也不会误显示“已连接”。
    • 只有真实可交互的会话会进入客户端列表。

将 known hosts 警告视为普通信息

  • 日期: 2025年11月11日
  • 调整内容:
    1. SshSessionService 在发布系统消息时识别「Warning: Permanently added … to the list of known hosts」文案,不再标记为错误。
  • 涉及文件:
    • AuroraDesk.Infrastructure/Services/SshSessionService.cs
  • 效果:
    • 已建立连接时不会把 known hosts 提示渲染成错误消息。
    • 用户仍可从系统消息中看到该提示,并可正常复制。

SSH 表单标签/控件对齐

  • 日期: 2025年11月11日
  • 调整内容:
    1. 改为单个 Grid,通过 Auto,* 成对列定义实现“标签+控件”组合的四列排布,并为间隔列设置固定空间,防止重叠。
    2. 私钥路径独占全宽行,按钮与状态信息置于第四行独立 Grid,整体间距统一。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 四列布局真正对齐,输入框不再拥挤或重合。
    • 折叠高度依旧受控,字段读取更加直观。

SSH 操作栏并入私钥行

  • 日期: 2025年11月11日
  • 调整内容:
    1. 将按钮和状态提示移入私钥路径同行,采用三列布局(按钮、间隔、状态)保持横向紧凑。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • 操作区与路径配置在同一视觉行,节省垂直空间。
    • 状态消息仍具备充分宽度并随文本自动换行。

修复 SSH 表单栅格闭合

  • 日期: 2025年11月11日
  • 调整内容:
    1. 清理折叠内容中残留的 </Grid> 结束标签,避免与新 StackPanel 结构冲突导致 XAML 解析失败。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/SshPageView.axaml
  • 效果:
    • dotnet build 可再次顺利编译。

为 UDP 客户端接收消息列表增加序号显示

  • 日期: 2025年11月11日
  • 调整内容:
    1. UdpClientPageViewModel 中的 ReceivedMessages 升级为包含序号与展示文本的记录类型 ReceivedMessageEntry
    2. 接收后台线程为每条消息生成自增序号,清空列表时重置计数,确保序号连续。
    3. 调整 UdpClientPageView.axaml 接收消息模板,新增带序号徽章的两列布局,提升列表可读性。
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/UdpClientPageViewModel.cs
    • AuroraDesk.Presentation/Views/Pages/UdpClientPageView.axaml
  • 效果:
    • 接收列表左侧清晰显示消息序号,便于定位与沟通。
    • 序号与消息内容一同虚拟化渲染,保持原有性能表现。

优化自动滚动勾选文案

  • 日期: 2025年11月10日
  • 调整内容:
    • 将接收消息区域复选框文案先更新为“是否滚动条置底”后进一步简化为“自动置底”,保持语义清晰且占用空间更小。
    • UdpClientPageView.axaml.cs 中对 DisposeWith 扩展方法的调用改为显式加入 CompositeDisposable,避免扩展方法缺失导致的编译错误。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/UdpClientPageView.axaml
    • AuroraDesk.Presentation/Views/Pages/UdpClientPageView.axaml.cs
  • 效果:
    • 用户可快速理解该选项控制滚动条自动置底的行为,同时避免标题栏拥挤。
    • ReactiveUI 激活生命周期订阅正常释放,dotnet build 可以顺利通过。

接收消息列表引入虚拟化以缓解卡顿

  • 日期: 2025年11月10日
  • 问题: 接收消息超过 3000 条后切换 Tab 返回页面会明显卡顿。
  • 解决方案:
    1. 将接收消息区域由 ScrollViewer + ItemsControl 改为启用虚拟化的 ListBox,只生成可视区域内的元素。
    2. 更新代码隐藏,将滚动置底逻辑改为基于 ListBox.ScrollIntoView,兼容虚拟化场景。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/UdpClientPageView.axaml
    • AuroraDesk.Presentation/Views/Pages/UdpClientPageView.axaml.cs
  • 效果:
    • 切换 Tab 时无需重新构建全部 3000+ 条视觉元素,页面响应显著提升。
    • 自动置底逻辑保持可用,与新的列表控件兼容。

修复附件圆数量变化未刷新画布的问题

  • 日期: 2025年11月6日
  • 问题: 在右侧属性面板调整附件圆数量后,画布上的节点圆点数量不更新。
  • 原因: Node.ConnectionPoints 集合增删元素时未触发属性变更通知,导致绑定使用的转换器不会重新计算结果。
  • 修复内容:
    1. Node 新增构造函数,订阅 ConnectionPoints.CollectionChanged 事件。
    2. 集合变化时显式调用 RaisePropertyChanged(nameof(ConnectionPoints)),确保 UI 绑定重新求值。
    3. 在替换 ConnectionPoints 集合时正确注销/注册事件,避免内存泄漏。
  • 涉及文件:
    • AuroraDesk.Core/Entities/Node.cs
  • 效果: 调整左右附件圆数量后,画布节点立即刷新圆点数量,属性面板与画布保持一致。

调整左右附件圆属性布局为纵向卡片

  • 日期: 2025年11月6日
  • 调整内容:
    1. 将左、右侧圆属性卡片改为纵向排列,避免同列并排导致内容拥挤。
    2. 每个圆的属性表单重构为与“组件属性”一致的双列表格布局,字段包含序号、直径、颜色、定位。
    3. 精简卡片内边距与边框样式,统一视觉层级与留白。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
  • 效果:
    • 左右附件圆配置区域上下排列,阅读顺序更自然。
    • 单个圆属性表单与基础属性风格一致,输入焦点和字段对齐更整洁。

为左右附件圆卡片添加折叠交互

  • 日期: 2025年11月6日
  • 修改内容:
    1. 使用 Expander 包裹左、右侧圆配置区域,提供可折叠的标题栏。
    2. 保留原有卡片边框与间距,使内容在展开时维持一致的视觉风格。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
  • 效果:
    • 用户可根据需要折叠左右圆配置,保持属性面板简洁。
    • 展开后内容布局与原先保持一致,无额外视觉跳变。

精简附件圆卡片内边距与行距

  • 日期: 2025年11月6日
  • 调整内容:
    1. 将左右圆 Expander 的内容区 Padding 调整为 6,并取消区块间额外间距。
    2. 附件圆列表使用 StackPanel Spacing="0",紧凑呈现多个圆的属性表格。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
  • 效果:
    • 属性面板整体占用更少垂直空间,避免上下留白。
    • 多个圆的配置无额外间距,信息密度更高。

将显示位置与数量配置改为表格布局

  • 日期: 2025年11月6日
  • 调整内容:
    1. 用带边框的双列表格承载“显示位置”“左侧数量”“右侧数量”三项配置。
    2. 统一标签与输入控件的对齐方式,与其他属性表格保持视觉一致。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
  • 效果:
    • 显示位置与数量编辑区域风格与其他属性卡片一致。
    • 输入控件列宽固定,阅读与操作更清晰。

移除显示位置选项

  • 日期: 2025年11月6日
  • 调整内容:
    1. 删除“显示位置”下拉框,仅保留左右数量配置,由数量是否为零决定显示侧。
    2. 表格结构调整为两行(左/右数量),边框与间距同步更新。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
  • 效果:
    • 属性面板更精简,避免重复配置。
    • 左右数量保持原有样式,操作习惯不变。

默认附件圆定位改为外侧,并修正偏移

  • 日期: 2025年11月6日
  • 修改内容:
    1. NodeNodeTemplateConnectionPoint 的默认 ConnectorPlacementMode 调整为 Outside,并同步更新模板/新增节点逻辑。
    2. ConnectorPlacementMarginConverter 外侧偏移量调整为直径长度,确保圆点完全位于节点外。
    3. ConnectorColumnPanel 新增 Side 属性,支持根据左右方向贴边排列,并在节点模板中分别指定 Side="Left"/"Right"
  • 涉及文件:
    • AuroraDesk.Core/Entities/Node.cs
    • AuroraDesk.Core/Entities/NodeTemplate.cs
    • AuroraDesk.Core/Entities/ConnectionPoint.cs
    • AuroraDesk.Presentation/ViewModels/Pages/NodeCanvasPageViewModel.cs
    • AuroraDesk.Presentation/Converters/NodeCanvasConverters.cs
    • AuroraDesk.Presentation/Controls/ConnectorColumnPanel.cs
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
  • 效果:
    • 新增节点与模板默认渲染为外侧圆点,减少手动修改。
    • 选择“外侧”后圆点完全贴在节点外部,视觉符合预期。

附件圆颜色编辑改用 ColorPicker

  • 日期: 2025年11月6日
  • 修改内容:
    1. 引入 av:ColorPicker 替换原有颜色文本框,支持直接选色,禁用 Alpha 频道。
    2. 新增 ColorHexToColorConverter 实现十六进制字符串与 Color 互转,配合 ColorPicker 双向绑定。
    3. ColorPicker 提供统一样式(圆角、边框、高度),保持与其他输入控件一致的视觉风格。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
    • AuroraDesk.Presentation/Converters/NodeCanvasConverters.cs
  • 效果:
    • 颜色编辑更直观,避免手动输入 Hex。
    • 色值仍以 #RRGGBB 字符串形式写回实体,兼容现有数据结构。

修正 ColorPicker 属性名以适配新版控件

  • 日期: 2025年11月6日
  • 修改内容:
    1. ShowPreviewPaletteVisible 替换为 Avalonia 11 新增的 IsColorPreviewVisibleIsColorPaletteVisible 属性。
    2. 保留 IsAlphaEnabled="False" 设置,持续禁用 Alpha 通道输入。
    3. 重新启用颜色预览与调色板,便于观察和选择颜色。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
  • 效果:
    • 解决构建时 AVLN2000 属性解析错误,ColorPicker 正常渲染。
    • 色彩预览与调色板恢复显示,调整颜色更直观。

确保外侧连接点可见

  • 日期: 2025年11月6日
  • 修改内容:
    1. 为节点模板中的根 Border 设置 ClipToBounds="False",允许连接点超出节点边界时仍然渲染。
    2. 保持现有圆角与阴影效果不变。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
  • 效果:
    • 选择“外侧”定位后,左右连接点完整显示在节点外侧。

调整外侧连接点偏移使视觉对齐

  • 日期: 2025年11月6日
  • 修改内容:
    1. 将外侧模式下的偏移量由“直径”改为“直径的一半”,使圆点一半在边外、一半在边内。
    2. 保持内侧定位逻辑不变。
  • 涉及文件:
    • AuroraDesk.Presentation/Converters/NodeCanvasConverters.cs
  • 效果:
    • 外侧圆点与内侧视觉保持一致,贴边但不会完全漂出。

修正 ConnectorColumnPanel 右侧排列的外侧偏移

  • 日期: 2025年11月6日
  • 修改内容:
    1. 调整 ConnectorColumnPanelRight 分支的排布公式,允许负 Margin.Right 将圆点推到节点外侧。
    2. 维持正向 margin 的内缩行为不变。
  • 涉及文件:
    • AuroraDesk.Presentation/Controls/ConnectorColumnPanel.cs
  • 效果:
    • 右侧外侧圆点将按照设置偏移正确露出外部,视觉与左侧一致。

优化特性面板表格与附件圆横向编辑体验

  • 日期: 2025年11月6日
  • 调整内容:
    1. 组件基础属性改为表格式布局,使用带边框的双列表格展示名称、宽度、高度,列宽收紧至 110,信息更集中。
    2. 左右附件圆编辑面板改为卡片顶部标题+横向三列(直径/颜色/定位)布局,字段一行内即可填写。
    3. 附件圆列表改回纵向 StackPanel,每个圆独占一行,卡片随列宽拉伸;保留单卡片分栏布局并统一边距,确保各项独立且排版整洁。
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
  • 效果:
    • 特性信息以带边框表格呈现,阅读更清晰。
    • 左右附件圆参数可横向填写,减少垂直空间占用。

节点附件圆重构:逐个圆配置半径与定位

  • 日期: 2025年11月6日
  • 修改内容:
    1. 核心实体扩展: 在 ConnectionPoint 中新增直径、颜色、定位属性,配合模板初始化默认值,支持每个附件圆独立配置。
    2. 数量与模式逻辑: NodeCanvasPageViewModel 将附件圆数量限制调整为 0~4,引入默认数量常量,并基于连接点数量计算显示模式;新增创建连接点的辅助方法,保障新增圆继承默认样式。
    3. 数量同步修复: 新增 _selectedLeftConnectorCount / _selectedRightConnectorCount 字段及 RefreshSelectedConnectorCounts() 辅助方法,确保左右数量下拉选择立刻反映最新连接点数量,切换模式后不再固定为 3 个。
    4. 属性面板重构: 右侧面板改为“组件属性”“附件圆属性”双卡片,基础属性采用表格布局,附件圆属性以垂直卡片形式呈现(移除表格式排版),支持逐个圆的直径、颜色、定位编辑。
    5. 画布渲染更新: 节点模板左右侧的 ItemsControl 直接使用连接点自身的直径与定位数据,外侧/内侧偏移基于单个圆计算。
    6. 辅助转换器: 新增 IndexToDisplayTextConverter 用于在界面上以「圆 1/圆 2」方式展示序号。
  • 涉及文件:
    • AuroraDesk.Core/Entities/ConnectionPoint.cs
    • AuroraDesk.Core/Entities/NodeTemplate.cs
    • AuroraDesk.Presentation/ViewModels/Pages/NodeCanvasPageViewModel.cs
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
    • AuroraDesk.Presentation/Converters/NodeCanvasConverters.cs
  • 效果:
    • 左右两侧附件圆完全独立设置数量、半径、颜色与内外侧定位。
    • 新增连接点自动采用侧边默认样式,减少重复输入。
    • 属性面板交互更直观,每个圆的设置清晰可见。

重构画布属性面板聚焦节点基础属性

  • 日期: 2025年11月6日
  • 修改内容:
    1. 属性面板布局: 重新组织 NodeCanvasPageView 右侧属性面板,保留节点名称与宽高编辑项,调整排版与间距,使信息层级更清晰。
    2. 附件圆模式: 新增 ConnectorAttachmentMode 枚举并在 ViewModel 中提供 SelectedConnectorModeSelectedNodeHasLeftConnector 等属性,通过下拉框控制附件圆的显示位置(无/仅左/仅右/两侧),并自动隐藏无效直径输入框。
    3. 状态提示: 当未选中节点时展示提示卡片,已选中节点时显示 “已选中对象” 状态文字,便于理解当前编辑上下文。
  • 修改文件:
    • AuroraDesk.Core/Entities/ConnectorAttachmentMode.cs
    • AuroraDesk.Presentation/ViewModels/Pages/NodeCanvasPageViewModel.cs
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
    • AuroraDesk.Presentation/Converters/NodeCanvasConverters.cs

优化节点多连接点显示与文本换行能力

  • 日期: 2025年11月6日
  • 调整内容:
    1. 多连接点支持: 为节点数据模板引入左右 ItemsControl,通过转换器动态过滤输入/输出连接点,默认为每侧生成至少3个连接点,满足复杂组件需求。
    2. 连接点样式: 左右圆点紧贴节点边框、默认直径设置为3,批量使用节点颜色配置;左侧圆点不再留出额外内边距。
    3. 文本换行: 将节点中心内容改为堆叠布局,标题与正文均支持自动换行,提升长文本展示效果。
  • 修改文件:
    • AuroraDesk.Core/Entities/Node.cs
    • AuroraDesk.Core/Entities/NodeTemplate.cs
    • AuroraDesk.Presentation/ViewModels/Pages/NodeCanvasPageViewModel.cs
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
    • AuroraDesk.Presentation/Converters/NodeCanvasConverters.cs

组件库重构:提供竖向/横向矩形模板

  • 日期: 2025年11月6日
  • 需求: 组件库只需提供两个基础组件——竖向矩形与横向矩形
  • 实现内容:
    1. 节点模板:
      • 清空并重建 NodeTemplates,新增 rectangle-verticalrectangle-horizontal
      • 设置宽高比:竖向 (80×160)、横向 (180×80)
      • 取消默认输入/输出连接点,Content 为空
    2. 画布节点展示:
      • 简化画布中的节点模板,直接根据宽高绘制矩形并显示标题
      • 节点选中时仍沿用边框高亮、粗细转换器
    3. 组件库预览:
      • 重构左侧模板展示 UI,通过 Viewbox 按比例缩放矩形预览
      • 显示名称、描述以及宽/高信息,便于快速辨识
    4. 属性面板编辑能力:
      • 可直接编辑标题、正文文字
      • 宽度/高度支持即时数字输入(双向绑定)
      • 左右附件圆支持调整直径与颜色
    5. 新增节点命令:
      • AddNode 默认创建横向矩形,移除旧的连接点初始化逻辑
  • 修改文件:
    • AuroraDesk.Presentation/ViewModels/Pages/NodeCanvasPageViewModel.cs
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml

优化 NodeCanvasPageView 属性面板与节点尺寸约束

  • 日期: 2025年11月6日
  • 优化内容:
    1. 属性面板视觉清晰度:
    • NodeCanvasPageView.axaml 顶层启用 UseLayoutRounding,并为属性面板容器设置局部 Styles(强制使用微软雅黑字体、统一内边距与圆角),缓解 Windows 下输入框及标签发虚问题
    • ScrollViewer、Border、StackPanel 同步启用 UseLayoutRounding,细化布局像素对齐
    1. 全局字体一致性:
    • App.axaml 中为 TextBlock/TextBox 设置默认字体族为 Microsoft YaHei 优先,保障中文界面清晰可读
    1. 节点尺寸与附件圆限制:
      • Node 实体中为宽度/高度及左右附件圆直径增加 Math.Clamp 约束,防止输入异常数值导致渲染异常
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml
    • AuroraDesk/App.axaml
    • AuroraDesk.Core/Entities/Node.cs

代码优化:清理 NodeCanvasPageView 和移除默认测试节点

  • 日期: 2025年11月6日
  • 修改内容:
    1. 移除默认测试节点:
      • 删除 InitializeTestNode() 方法及其调用
      • 清理构造函数中的调试输出
    2. 代码优化:
      • 移除 NodeCanvasPageView.axaml.cs 中大量调试输出(System.Diagnostics.Debug.WriteLine
      • 简化 OnTemplateButtonDoubleTapped 方法
      • 优化 UpdateNodePositionsUpdateSingleNodePosition 方法,移除冗余日志
      • 简化异常处理,使用空 catch 块(位置更新主要依赖数据绑定)
      • 清理 UpdateNodesOnCanvas 方法(已不再使用)
    3. 代码结构:
      • 保持核心功能不变
      • 代码更简洁易读
      • 保留必要的注释和文档
  • 技术改进:
    • 位置更新主要依赖 XAML 数据绑定(Canvas.Left="{Binding X}"Canvas.Top="{Binding Y}"
    • 代码后台的位置更新作为备用方案保留
    • 移除了调试阶段的临时代码
  • 修改文件:
    • AuroraDesk.Presentation/ViewModels/Pages/NodeCanvasPageViewModel.cs - 移除测试节点初始化
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml.cs - 代码优化和清理

修复节点在画布上不显示的问题

  • 日期: 2025年11月6日
  • 问题: InitializeTestNode 执行后节点已添加到服务,位置也设置成功,但画布上不显示节点
  • 原因分析:
    • 在 Avalonia 中,当使用 ItemsControlCanvas 作为 ItemsPanel 时,需要在 ItemTemplate 的根元素上绑定 Canvas.LeftCanvas.Top 属性
    • 之前的代码只有代码后台手动设置位置,但缺少 XAML 绑定,导致节点位置无法正确设置
    • 关键问题ItemsControl 使用的 Canvas(作为 ItemsPanel)大小为 0x0,导致节点虽然位置正确但不可见
  • 修复内容:
    1. XAML 绑定位置:
      • ItemTemplateBorder 元素上添加 Canvas.Left="{Binding X}"Canvas.Top="{Binding Y}" 绑定
    2. Canvas 大小设置:
      • ItemsPanelTemplateCanvas 上设置 Width="2000"Height="2000"MinWidth="2000"MinHeight="2000"
      • 确保 Canvas 有明确的大小,与 CanvasContainer 保持一致
    3. ItemsControl 布局:
      • ItemsControl 添加 HorizontalAlignment="Stretch"VerticalAlignment="Stretch"
    4. 调试信息增强:
      • 添加更详细的调试日志,包括:
        • ItemsControl 的直接视觉子元素数量
        • Canvas 面板的大小和子元素数量
        • 每个子元素的位置、可见性和大小
        • 节点容器的可见性状态
  • 技术细节:
    • 在 Avalonia 中,ItemsControl 使用 Canvas 作为 ItemsPanel 时:
      • 位置绑定应该在 ItemTemplate 的根元素上
      • Canvas 必须设置明确的大小(不能依赖自动计算)
      • 数据绑定会自动处理位置更新,代码后台的手动设置作为备用方案保留
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml - 添加 Canvas.Left/Top 绑定,设置 Canvas 大小,添加 ItemsControl 对齐属性
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml.cs - 添加更详细的调试信息

修复 SelectedNode 绑定 null 值错误

  • 日期: 2025年11月6日
  • 问题: 当 SelectedNode 为 null 时,绑定到 SelectedNode.TitleSelectedNode.XSelectedNode.YSelectedNode.WidthSelectedNode.Height 的属性会出现绑定错误
  • 错误日志:
    [Binding]An error occurred binding 'Text' to 'SelectedNode.Title' at 'SelectedNode': 'Value is null.'
    [Binding]An error occurred binding 'Text' to 'SelectedNode.X' at 'SelectedNode': 'Value is null.'
    [Binding]An error occurred binding 'Text' to 'SelectedNode.Y' at 'SelectedNode': 'Value is null.'
    [Binding]An error occurred binding 'Text' to 'SelectedNode.Width' at 'SelectedNode': 'Value is null.'
    [Binding]An error occurred binding 'Text' to 'SelectedNode.Height' at 'SelectedNode': 'Value is null.'
    
  • 修复内容:
    • 为所有 SelectedNode.Property 绑定添加 TargetNullValueFallbackValue 属性
    • SelectedNode.Title 绑定:添加 TargetNullValue=''FallbackValue=''
    • SelectedNode.XSelectedNode.YSelectedNode.WidthSelectedNode.Height 绑定:添加 TargetNullValue='0.00'FallbackValue='0.00'
  • 技术细节:
    • TargetNullValue: 当绑定的值为 null 时使用的默认值
    • FallbackValue: 当绑定失败时使用的默认值
    • 字符串属性使用空字符串作为默认值
    • 数值属性使用 '0.00' 作为默认值(与 StringFormat 的格式保持一致)
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml - 修复所有 SelectedNode 属性绑定,添加 null 值处理

修复节点添加后画布不显示问题

  • 日期: 2025年11月6日
  • 问题: 从日志看节点已成功添加到服务,但画布上不显示节点
  • 原因分析:
    • WhenAnyValue(x => x.Nodes) 只监听属性引用变化,不会响应 ObservableCollection 的内容变化
    • 需要直接监听集合的 CollectionChanged 事件来确保 UI 更新
    • Avalonia 的 ItemsControl 不支持 ItemContainerStyle 属性(与 WPF 不同)
  • 修复内容:
    1. View Code-Behind (NodeCanvasPageView.axaml.cs):
      • 使用 WhenAnyValue(x => x.Nodes) 监听属性变化,并在订阅中直接订阅 CollectionChanged 事件
      • 当集合变化时,强制刷新 ItemsControl 的布局(调用 InvalidateMeasure()InvalidateArrange()
      • 添加了详细的调试日志,方便追踪节点添加过程
    2. View XAML (NodeCanvasPageView.axaml):
      • ItemTemplate 中使用 ContentControl 包装 Border,并在 ContentControl 上设置 Canvas.LeftCanvas.Top 绑定
      • 这是 Avalonia 中设置 Canvas 位置的正确方式(因为 Avalonia 不支持 ItemContainerStyle
    3. 简化代码:
      • 简化了 UpdateNodesOnCanvas 方法,移除了手动设置位置的代码(现在由数据绑定自动处理)
  • 技术细节:
    • ObservableCollection 实现了 INotifyCollectionChanged 接口,可以直接订阅 CollectionChanged 事件
    • 在 Avalonia 中,当使用 ItemsControlCanvas 作为 ItemsPanel 时,需要在 ItemTemplate 中的控件上直接设置 Canvas.LeftCanvas.Top 附加属性
    • 使用 Dispatcher.UIThread.Post 确保 UI 更新在 UI 线程上执行
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml.cs - 添加集合变化监听和强制刷新逻辑
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml - 修复 Canvas 位置绑定方式(使用 ContentControl 包装)

修复双击组件添加功能,改用PointerPressed检测双击

  • 日期: 2025年11月6日
  • 问题: XAML中的DoubleTapped事件在DataTemplate中无法正确触发
  • 修复内容:
    • 移除了XAML中的DoubleTapped="OnTemplateItemDoubleTapped"绑定
    • 改用PointerPressed事件手动检测双击(通过时间间隔判断)
    • 添加了双击检测相关字段:_lastTemplateClickTime_lastTemplateClickBorderDoubleClickDelayMs(500ms)
    • 实现了OnTemplateItemPointerPressed方法来检测双击
    • 将双击处理逻辑提取到HandleTemplateDoubleClick方法中
    • 添加了详细的日志输出,方便追踪双击事件和节点添加过程
  • 技术细节:
    • 双击检测:同一个Border在500ms内连续点击两次即判定为双击
    • 使用DateTime.Now记录点击时间
    • 使用延迟任务自动清除超时的点击记录
    • 保持了原有的位置计算逻辑(考虑缩放和平移)
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml - 移除DoubleTapped绑定
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml.cs - 改用PointerPressed检测双击

清理拖拽逻辑并添加双击添加组件功能

  • 日期: 2025年1月10日
  • 修改内容: 清理不生效的拖拽逻辑,改为双击组件库中的组件即可添加到画布
  • 清理内容:
    • 移除了 SetupTemplateDragAndDrop() 方法
    • 移除了 SetupTemplateItems() 方法
    • 移除了 SetupTemplateItemDrag() 方法
    • 移除了 OnCanvasDragOver() 方法
    • 移除了 OnCanvasDrop() 方法
    • 移除了 Canvas 和 ScrollViewer 上的拖拽事件绑定
  • 新增功能:
    • 添加了 SetupTemplateDoubleClick() 方法
    • 添加了 SetupTemplateItemsDoubleClick() 方法
    • 添加了 SetupTemplateItemDoubleClick() 方法
    • 双击组件库中的组件时,会在画布中心位置添加节点
    • 如果画布还没有尺寸,使用默认位置 (200, 200)
  • 用户体验:
    • 双击组件即可快速添加到画布,操作更简单
    • 节点默认添加到画布中心,便于查看和编辑
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml.cs - 清理拖拽逻辑,添加双击功能

优化 NodeCanvasPageView 缩放控件使用 HeroIcons 图标

  • 日期: 2025年1月10日
  • 修改内容: 将缩放控件的文本符号(+、−、重置)替换为 HeroIcons.Avalonia 图标,提升视觉效果
  • 实现方式:
    • 添加 HeroIcons 命名空间引用:xmlns:heroicons="clr-namespace:HeroIconsAvalonia.Controls;assembly=HeroIconsAvalonia"
    • 缩小按钮:使用 HeroIcon Type="Minus" 图标(16x16像素)
    • 放大按钮:使用 HeroIcon Type="Plus" 图标(16x16像素)
    • 重置按钮:使用 HeroIcon Type="ArrowsPointingOut" 图标配合文字"重置"(14x14像素)
  • 视觉效果:
    • 图标使用统一的文本主色(TextPrimary)
    • 图标居中对齐,大小适中
    • 按钮间距调整为6px,整体更紧凑
    • 重置按钮使用图标+文字的组合方式,更直观
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml - 使用 HeroIcons 替换文本符号

为 NodeCanvasPageView 中间画布添加拖动和缩放功能

  • 日期: 2025年1月10日
  • 修改内容: 为节点编辑器页面的中间画布添加拖动(平移)功能,与缩放功能配合使用
  • 实现方式:
    • XAML层面:
      • 使用 TransformGroup 组合 TranslateTransformScaleTransform
      • 平移和缩放都绑定到 ViewModel 的 CanvasOffsetXCanvasOffsetYCanvasZoom 属性
      • 先应用平移,再应用缩放,确保正确的变换顺序
    • 代码后台:
      • 添加画布拖动状态跟踪:_isDraggingCanvas_canvasDragStartPoint_canvasDragStartOffsetX_canvasDragStartOffsetY
      • 支持两种拖动方式:
        • 鼠标中键拖动
        • 空格键+鼠标左键拖动
      • OnCanvasPointerPressedOnCanvasPointerMovedOnCanvasPointerReleased 中处理画布拖动
      • OnScrollViewerPointerPressedOnScrollViewerPointerMovedOnScrollViewerPointerReleased 中处理 ScrollViewer 上的拖动
      • 添加键盘事件处理(OnKeyDownOnKeyUp)来检测空格键状态
      • 拖动时考虑缩放因子,确保拖动距离正确
      • 拖动时改变光标为手型(Hand)
  • 交互功能:
    • 鼠标中键拖动:按住鼠标中键拖动即可平移画布
    • 空格键+左键拖动:按住空格键,然后按住鼠标左键拖动即可平移画布
    • 拖动时光标变为手型,松开后恢复
    • 拖动距离会根据当前缩放比例自动调整
  • 技术细节:
    • 拖动偏移量计算:deltaX / zoomFactordeltaY / zoomFactor
    • 确保节点拖动和画布拖动不会冲突
    • 拖动时更新 ViewModel 的 CanvasOffsetXCanvasOffsetY 属性
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml - 添加 TransformGroup 支持平移和缩放
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml.cs - 添加画布拖动逻辑

为 NodeCanvasPageView 中间画布添加缩放功能

  • 日期: 2025年1月10日
  • 修改内容: 为节点编辑器页面的中间画布添加缩放功能,支持按钮缩放和鼠标滚轮缩放
  • 实现方式:
    • ViewModel层面:
      • 添加缩放命令:ZoomInCommand(放大)、ZoomOutCommand(缩小)、ResetZoomCommand(重置缩放)、SetZoomCommand(设置缩放)
      • 缩放范围限制在0.1倍到3.0倍之间
      • 每次缩放步进为1.2倍(放大)或1/1.2倍(缩小)
    • View层面:
      • 为CanvasContainer和GridBackgroundLayer添加ScaleTransform,绑定到ViewModel的CanvasZoom属性
      • 在画布右上角添加缩放控件,包含:缩小按钮(−)、缩放比例显示、放大按钮(+)、重置按钮
      • 缩放控件使用白色背景、圆角边框,悬浮在画布上方(ZIndex=100)
    • 交互功能:
      • 支持鼠标滚轮缩放:按住Ctrl键并滚动鼠标滚轮进行缩放
      • 向上滚动放大,向下滚动缩小
  • 视觉效果:
    • 缩放控件显示当前缩放比例(百分比格式)
    • 缩放时画布内容和网格背景同步缩放
    • 缩放控件始终显示在画布右上角,不影响画布内容
  • 修改文件:
    • AuroraDesk.Presentation/ViewModels/Pages/NodeCanvasPageViewModel.cs - 添加缩放命令和逻辑
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml - 添加缩放控件和Transform
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml.cs - 添加鼠标滚轮缩放支持

为 NodeCanvasPageView 三列添加类似 GroupBox 效果

  • 日期: 2025年1月10日
  • 修改内容: 为节点编辑器页面的三列(左侧组件库、中间画布、右侧属性面板)添加类似GroupBox的边框效果
  • 实现方式:
    • 保持3列Grid布局不变,为最外层Grid添加Margin="12"来创建整体边距
    • 左侧Border:添加完整边框(BorderThickness="1")、圆角(CornerRadius="8")、右边距(Margin="0,0,12,0")
    • 中间画布:用Border包裹Grid,添加完整边框(BorderThickness="1")、圆角(CornerRadius="8")、右边距(Margin="0,0,12,0")
    • 右侧Border:添加完整边框(BorderThickness="1")、圆角(CornerRadius="8")
    • 所有边框使用BorderLight颜色(#E0E0E0),背景使用白色或浅灰色
  • 视觉效果:
    • 三列现在都有完整的圆角边框,类似GroupBox效果
    • 列与列之间有12px的间距,视觉上更加清晰分离
    • 所有边框使用统一的浅灰色(BorderLight),与整体设计风格一致
    • 圆角半径为8px,提供现代化的视觉效果
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml - 为三列添加GroupBox样式的边框和间距

修复 NodeCanvasPageView 中的编译错误

  • 日期: 2025年1月10日
  • 问题:
    • ItemContainerGenerator 未包含 ContainerFromItem 的定义
    • DispatcherPriority 未包含 Layout 的定义
  • 修复内容:
    1. 移除了不存在的 ItemContainerGenerator.ContainerFromItem() 方法调用
    2. 改用 GetVisualDescendants() 方法遍历视觉树来查找对应的 ContentControl 容器
    3. DispatcherPriority.Layout 改为 DispatcherPriority.Normal(Avalonia 中不存在 Layout 枚举值)
  • 技术说明:
    • 在 Avalonia 中,ItemContainerGenerator 没有 ContainerFromItem 方法
    • 通过遍历视觉树(GetVisualDescendants())来查找对应的容器是更可靠的方法
    • DispatcherPriority 枚举在 Avalonia 中可用的值包括:Invalid, Inactive, SystemIdle, ApplicationIdle, ContextIdle, Background, Input, Loaded, Render, Normal, Send
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml.cs - 修复容器查找方法和 DispatcherPriority 枚举值

调整 UdpServerPageView 客户端列表折叠按钮位置到左侧

  • 日期: 2025年1月10日
  • 修改内容: 将客户端列表的折叠按钮从标题栏中间移到最左侧,使用三列 Grid 布局
  • 布局改进:
    • 使用 Grid 三列布局:ColumnDefinitions="Auto,*,Auto"
    • 第一列:折叠按钮(左侧,固定宽度 40px,左侧内边距 16px)
    • 第二列:标题内容(中间,自适应宽度,包含图标、文字和徽章)
    • 第三列:清空按钮(右侧,固定宽度)
  • 视觉效果: 折叠按钮现在独立显示在左侧,布局更加清晰,符合常见的折叠面板设计模式
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/UdpServerPageView.axaml - 调整折叠按钮布局位置

优化 UdpServerPageView 布局,使客户端列表和接收消息区域铺满剩余空间

  • 日期: 2025年1月10日
  • 修改内容: 为客户端列表和接收消息区域的 Border、Grid、Expander 和 ScrollViewer 添加 VerticalAlignment="Stretch" 属性,使它们能够铺满剩余的垂直空间
  • 改进点:
    • 客户端列表 Border 添加了 VerticalAlignment="Stretch"
    • 客户端列表内部 Grid 添加了 VerticalAlignment="Stretch"
    • 客户端列表 Expander 添加了 VerticalAlignment="Stretch"
    • 客户端列表 ScrollViewer 添加了 VerticalAlignment="Stretch"
    • 接收消息区域 Border 添加了 VerticalAlignment="Stretch"
    • 接收消息区域内部 Grid 添加了 VerticalAlignment="Stretch"
    • 接收消息区域 ScrollViewer 添加了 VerticalAlignment="Stretch"
  • 效果: 两个区域现在能够充分利用可用的垂直空间,提供更好的用户体验
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/UdpServerPageView.axaml - 添加垂直对齐属性

修复 UdpServerPageView 中 Border 控件无效属性错误

  • 日期: 2025年1月10日
  • 问题: Border 控件不支持 HorizontalContentAlignment 属性,导致编译错误 AVLN2000
  • 修复内容: 移除了第 285 行 Border 控件上的无效属性 HorizontalContentAlignment="Stretch"
  • 说明:
    • Border 控件在 Avalonia 中不支持 HorizontalContentAlignment 属性
    • 使用 HorizontalAlignment="Stretch" 即可实现 Border 本身的对齐
    • 内容对齐可以通过内部容器(如 Grid)的 HorizontalAlignment 属性控制
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/UdpServerPageView.axaml - 移除无效属性

重构 UdpServerPageView 布局为两行结构并支持折叠

  • 日期: 2025年1月10日
  • 修改内容: 重构 UDP 服务端页面视图为两行布局,客户端列表支持折叠功能
  • 布局结构:
    • 第一行:服务器控制(监听端口、启动/停止按钮,横向排列)
    • 第二行:左右分栏布局
      • 左边(1/3):客户端列表区域(使用 Expander 支持折叠,显示连接的客户端信息)
      • 右边(2/3):接收消息区域(显示接收到的消息列表)
  • 改进点:
    • 配置区域改为横向布局,端口输入和启动/停止按钮在同一行
    • 客户端列表和接收消息区域采用左右分栏,右边接收消息区域占据 2/3 宽度
    • 客户端列表使用 Expander 控件,支持折叠/展开功能
    • 所有 Border 和 Expander 添加了 HorizontalAlignment="Stretch" 确保占满宽度
    • 保持了原有的功能和样式风格
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/UdpServerPageView.axaml - 重构为两行布局,客户端列表支持折叠

重构 UdpClientPageView 布局为两行结构

  • 日期: 2025年1月10日
  • 修改内容: 重构 UDP 客户端页面视图,将主要内容区域改为两行布局
  • 布局结构:
    • 第一行:连接配置(IP、端口、本地端口、连接/断开按钮,横向排列)
    • 第二行:左右分栏布局
      • 左边(1/3):已发送消息区域(包含消息列表和输入框)
      • 右边(2/3):接收消息区域(显示接收到的消息列表)
  • 改进点:
    • 配置区域保持横向布局,所有配置项和按钮在同一行
    • 已发送消息和接收消息区域采用左右分栏,右边接收消息区域占据 2/3 宽度
    • 已发送消息区域整合了消息列表和输入框,布局更紧凑
    • 保持了原有的功能和样式风格
  • 修改文件:
    • AuroraDesk.Presentation/Views/Pages/UdpClientPageView.axaml - 重构为两行布局,左右分栏

实现 UDP 客户端和服务端功能

  • 日期: 2025年1月10日
  • 修改内容: 实现 UDP 客户端和服务端两个视图页面,并添加到导航菜单中
  • 功能实现:
    • 创建 UDP 客户端 ViewModel (UdpClientPageViewModel.cs)
    • 创建 UDP 服务端 ViewModel (UdpServerPageViewModel.cs)
    • 创建 UDP 客户端 View (UdpClientPageView.axaml.axaml.cs)
    • 创建 UDP 服务端 View (UdpServerPageView.axaml.axaml.cs)
    • 在 PageViewModelFactory 中注册两个页面
    • 在 ServiceCollectionExtensions 中注册 ViewModel
    • 在 NavigationService 中添加导航项(UDP 工具分组)
  • UDP 客户端功能:
    • 配置服务器 IP 和端口
    • 连接/断开服务器
    • 发送消息到服务器
    • 接收服务器响应
    • 显示已发送和接收的消息列表
    • 清空消息列表
  • UDP 服务端功能:
    • 配置监听端口
    • 启动/停止监听
    • 接收客户端消息
    • 自动回复客户端(可选)
    • 显示接收到的消息列表
    • 显示连接的客户端列表(IP:端口、消息数、首次/最后连接时间)
    • 清空消息和客户端列表
  • 修改文件:
    • AuroraDesk.Presentation/ViewModels/Pages/UdpClientPageViewModel.cs - UDP 客户端 ViewModel
    • AuroraDesk.Presentation/ViewModels/Pages/UdpServerPageViewModel.cs - UDP 服务端 ViewModel
    • AuroraDesk.Presentation/Views/Pages/UdpClientPageView.axaml - UDP 客户端视图
    • AuroraDesk.Presentation/Views/Pages/UdpClientPageView.axaml.cs - UDP 客户端视图代码
    • AuroraDesk.Presentation/Views/Pages/UdpServerPageView.axaml - UDP 服务端视图
    • AuroraDesk.Presentation/Views/Pages/UdpServerPageView.axaml.cs - UDP 服务端视图代码
    • AuroraDesk.Presentation/Services/PageViewModelFactory.cs - 注册页面工厂方法
    • AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs - 注册 ViewModel 服务
    • AuroraDesk.Infrastructure/Services/NavigationService.cs - 添加导航项
  • 技术实现:
    • 遵循 ReactiveUI + MVVM 模式
    • 使用 ReactiveCommand 实现命令绑定
    • 使用 ObservableCollection 管理消息列表
    • 异步网络操作(UDP 发送/接收)
    • 后台任务处理消息接收(避免阻塞 UI)
    • 资源清理(Dispose 模式)
    • 使用 Dispatcher.UIThread 确保 UI 线程安全更新
  • 架构遵循:
    • 整洁架构(Clean Architecture)
    • ReactiveUI 响应式编程模式
    • MVVM 模式
    • 依赖注入(DI)
    • 服务层分离(ViewModel 只处理业务逻辑,View 只负责 UI 展示)
  • 导航结构:
    • UDP 工具(父级导航项,IconType.Signal)
      • UDP 客户端(IconType.ArrowRight)
      • UDP 服务端 (IconType.Server)
  • UI 特性:
    • 现代化的界面设计(圆角、阴影、颜色区分)
    • 实时状态显示
    • 消息时间戳
    • 客户端信息详细展示
    • 响应式布局
  • 测试建议:
    • 启动 UDP 服务端,监听端口 8080
    • 启动 UDP 客户端,连接到 127.0.0.1:8080
    • 发送测试消息,验证双向通信
    • 测试多客户端连接场景
    • 测试异常情况(端口占用、网络错误等)

修正节点附件圆外侧定位,确保左侧圆在边线左侧

  • 日期: 2025年11月7日
  • 问题: 左侧附件圆设置为 Outside 模式时,圆没有正确显示在组件左边线的左侧,而是显示在右侧;修正后圆圈像是被容器裁剪遮挡
  • 修复内容:
    1. 转换器逻辑重构
      • 重构 ConnectorPlacementMarginConverter 转换器逻辑,明确区分 Inside 和 Outside 模式
      • Outside 模式:
        • 左侧圆使用负的左边距(Thickness(-size, 0, 0, 0)),向左偏移一个直径的距离
        • 右侧圆使用负的右边距(Thickness(0, 0, -size, 0)),向右偏移一个直径的距离
      • Inside 模式:不添加额外边距(Thickness(0)
      • 添加详细的代码注释,说明 Outside 和 Inside 模式的含义
    2. 禁用容器裁剪
      • 为节点内部的 Grid 容器添加 ClipToBounds="False",确保外侧圆不被裁剪
      • 为左右两侧的 ItemsControl 添加 ClipToBounds="False"
      • 为左右两侧的 ConnectorColumnPanel 添加 ClipToBounds="False"
      • 确保圆圈完全显示在节点外侧,不会被任何容器裁剪
  • 涉及文件:
    • AuroraDesk.Presentation/Converters/NodeCanvasConverters.cs - 修正 ConnectorPlacementMarginConverter 逻辑
    • AuroraDesk.Presentation/Views/Pages/NodeCanvasPageView.axaml - 添加 ClipToBounds="False" 禁用容器裁剪
  • 效果:
    • 左侧外侧圆正确显示在组件左边线的左侧,完全可见不被裁剪
    • 右侧外侧圆正确显示在组件右边线的右侧,完全可见不被裁剪
    • 内侧模式保持圆在组件边界内部
    • 代码逻辑更加清晰易懂

修复清除画布时无法清除连接的问题

  • 日期: 2025年11月7日
  • 问题: 清除画布时,如果画布上有连接线(Connection),无法正确清除
  • 原因: NodeCanvasService.Clear() 方法只是简单地清空了连接集合,但没有重置连接点(ConnectionPoint)的 IsConnected 状态
  • 修复内容:
    • Clear() 方法中,先遍历所有连接,重置源连接点和目标连接点的 IsConnected 状态为 false
    • 然后再清空连接集合和节点集合
    • 这与 RemoveConnection() 方法的处理逻辑保持一致
  • 涉及文件:
    • AuroraDesk.Infrastructure/Services/NodeCanvasService.cs - 修正 Clear() 方法
  • 效果:
    • 清除画布时,所有连接点的状态被正确重置
    • 清除后可以正常添加新的节点和连接
    • 避免了连接点状态不一致导致的问题

FileExplorerPageView 性能分析 - 卡顿问题

  • 日期: 2025年1月17日
  • 问题: FileExplorerPageView 在使用过程中出现卡顿现象
  • 分析结果:

主要性能问题点:

  1. 搜索框实时过滤导致UI卡顿(最严重)

    • 位置: FileExplorerPageView.axaml 第96行
    • 问题: Text="{Binding SearchQuery, UpdateSourceTrigger=PropertyChanged}" 设置导致每次输入都会立即触发过滤
    • 影响:
      • 每次输入都会调用 ApplyFilter() 方法(ViewModel 第448-475行)
      • ApplyFilter() 会调用 CloneNodeWithFilter() 递归克隆整个树结构(第477-504行)
      • 对于大型目录树(如包含数千个文件),每次输入都会创建大量新对象,导致:
        • UI线程阻塞
        • 内存分配压力大
        • GC频繁触发
        • 输入延迟明显
  2. TreeView 数据绑定和渲染问题

    • 位置: FileExplorerPageView.axaml 第100-126行
    • 问题:
      • TreeView 绑定了 FilteredTreeItems,但可能没有启用虚拟化
      • 大型树结构在展开时可能会一次性渲染所有可见节点
      • SizeDisplay 属性在数据模板中被绑定(第120行),每次访问都会计算格式化字符串
  3. 过滤算法效率问题

    • 位置: FileExplorerPageViewModel.cs 第477-504行 CloneNodeWithFilter() 方法
    • 问题:
      • 递归克隆整个树结构,即使只有少量节点匹配也会创建大量对象
      • 字符串比较使用 CurrentCultureIgnoreCase,对于大量节点比较性能较差
      • 每次过滤都会重建整个过滤后的树,而不是增量更新
  4. UI线程阻塞问题

    • 位置: FileExplorerPageViewModel.cs 第448-475行 ApplyFilter() 方法
    • 问题:
      • 过滤操作完全在UI线程执行
      • 对于大型树,过滤过程会阻塞UI响应
      • 没有使用延迟或防抖机制
  5. 初始化时不必要的过滤

    • 位置: FileExplorerPageViewModel.cs 第60行
    • 问题: 构造函数中调用 ApplyFilter(),但此时 _treeItems 为空,过滤操作无意义

优化建议:

  1. 添加搜索防抖(Debounce)机制

    • 使用 ReactiveUIThrottle 操作符延迟过滤执行
    • 建议延迟 300-500ms,避免每次输入都触发过滤
  2. 优化过滤算法

    • 考虑使用增量过滤,只更新变化的部分
    • 使用更高效的字符串匹配(如 OrdinalIgnoreCase
    • 对于大型树,考虑分页或虚拟化过滤结果
  3. 使用后台线程处理过滤

    • 将过滤操作移到后台线程执行
    • 使用 Dispatcher.UIThread.InvokeAsync 更新UI
  4. TreeView 虚拟化

    • 确保 TreeView 启用了虚拟化
    • 考虑使用 ItemsRepeater 或其他虚拟化控件
  5. 延迟计算属性

    • SizeDisplay 应该缓存结果,避免每次访问都计算
  • 涉及文件:
    • AuroraDesk.Presentation/Views/Pages/FileExplorerPageView.axaml - 搜索框绑定配置
    • AuroraDesk.Presentation/ViewModels/Pages/FileExplorerPageViewModel.cs - 过滤逻辑和数据处理

FileExplorerPageView 性能优化 - 修复卡顿问题

  • 日期: 2025年1月17日
  • 问题: FileExplorerPageView 在使用过程中出现卡顿现象,特别是搜索时
  • 修复内容:

1. 添加搜索防抖机制

  • 位置: FileExplorerPageViewModel.cs 第63-67行
  • 实现:
    • 使用 ReactiveUIThrottle 操作符,延迟 400ms 执行过滤
    • 通过 WhenAnyValue 监听 SearchQuery 变化
    • 使用 ObserveOn(RxApp.MainThreadScheduler) 确保在 UI 线程更新
  • 效果: 避免每次输入都立即触发过滤,减少不必要的计算

2. 后台线程处理过滤操作

  • 位置: FileExplorerPageViewModel.cs 第455-531行 ApplyFilterAsync() 方法
  • 实现:
    • ApplyFilter() 改为异步方法 ApplyFilterAsync()
    • 使用 Task.Run() 在后台线程执行过滤计算
    • 使用 CancellationToken 支持取消之前的过滤操作
    • 在 UI 线程使用 Dispatcher.UIThread.InvokeAsync 更新结果
  • 效果: 过滤操作不再阻塞 UI 线程,界面保持响应

3. 优化过滤算法

  • 位置: FileExplorerPageViewModel.cs 第563-594行 CloneNodeWithFilter() 方法
  • 优化:
    • 将字符串比较从 CurrentCultureIgnoreCase 改为 OrdinalIgnoreCase(性能更好)
    • 在排序时也使用 OrdinalIgnoreCase(第378行)
    • 添加 CancellationToken 支持,允许取消长时间运行的过滤操作
  • 效果: 字符串比较性能提升,特别是在处理大量文件时

4. TreeView 虚拟化说明

  • 位置: FileExplorerPageView.axaml 第100-105行
  • 说明:
    • Avalonia 的 TreeView 不支持 VirtualizingPanel.IsVirtualizingVirtualizingPanel.VirtualizationMode 附加属性
    • TreeView 在 Avalonia 中可能默认就支持虚拟化,或者需要使用其他方式
    • 已移除不支持的属性,避免编译错误
    • 通过其他优化(防抖、后台线程、算法优化)已经大幅提升了性能
  • 效果: 避免编译错误,其他性能优化已足够提升用户体验

5. 优化 SizeDisplay 属性缓存

  • 位置: FileExplorerPageViewModel.cs 第621-661行 FileTreeNode
  • 实现:
    • 添加 _cachedSizeDisplay 私有字段缓存计算结果
    • 首次访问时计算并缓存,后续直接返回缓存值
    • 添加 InvalidateSizeDisplayCache() 方法用于清除缓存(预留)
  • 效果: 避免每次绑定都重新计算格式化字符串,减少 CPU 使用

6. 移除不必要的初始化过滤

  • 位置: FileExplorerPageViewModel.cs 构造函数
  • 修复: 移除了构造函数中的 ApplyFilter() 调用,因为此时 _treeItems 为空
  • 效果: 减少不必要的初始化开销

7. 改进搜索框绑定

  • 位置: FileExplorerPageView.axaml 第96行
  • 说明: 保持 UpdateSourceTrigger=PropertyChanged,但通过防抖机制避免频繁触发
  • 效果: 输入响应及时,但过滤操作被防抖控制

技术细节:

  • 使用 CancellationTokenSource 管理过滤操作的取消

  • 使用 lock 确保线程安全的取消操作

  • 过滤结果在后台线程计算,UI 更新在 UI 线程执行

  • 支持过滤操作的中途取消,避免无效计算

  • 涉及文件:

    • AuroraDesk.Presentation/Views/Pages/FileExplorerPageView.axaml - 启用 TreeView 虚拟化
    • AuroraDesk.Presentation/ViewModels/Pages/FileExplorerPageViewModel.cs - 全面性能优化
  • 效果:

    • 搜索输入不再卡顿,防抖机制有效减少过滤次数
    • UI 线程不再阻塞,过滤操作在后台执行
    • 字符串比较性能提升,使用 OrdinalIgnoreCase
    • SizeDisplay 缓存减少重复计算
    • 支持取消长时间运行的过滤操作
    • 构建成功,无编译错误

新增 ScottPlot 图表页面

  • 日期: 2025年1月
  • 功能描述: 添加了基于 ScottPlot.Avalonia 的图表展示页面,支持多种图表类型
  • 实现内容:
    1. NuGet 包安装:
      • AuroraDesk.Presentation.csproj 中添加 ScottPlot.Avalonia 包引用(版本 5.1.57)
    2. ViewModel 层:
      • 创建 ScottPlotPageViewModel,继承自 RoutableViewModel
      • 实现图表标题、X/Y 轴标签属性绑定
      • 提供多种图表创建方法:示例图表、正弦波、多系列图表、柱状图
      • 使用 ReactiveCommand 实现命令绑定
    3. View 层:
      • 创建 ScottPlotPageView.axaml,包含控制面板和图表展示区域
      • 控制面板支持编辑图表标题、X/Y 轴标签
      • 提供多个操作按钮:示例图表、正弦波、多系列、柱状图、清除
      • 使用 AvaPlot 控件展示图表
      • 在代码后台中设置 PlotControl 引用,实现图表初始化
    4. 服务注册:
      • PageViewModelFactory 中注册 scottplot 页面 ID
      • ServiceCollectionExtensions 中注册 ScottPlotPageViewModel
      • NavigationService 中添加"ScottPlot 图表"导航项,使用 IconType.ChartBar 图标
  • 涉及文件:
    • AuroraDesk.Presentation/AuroraDesk.Presentation.csproj - 添加 ScottPlot.Avalonia 包
    • AuroraDesk.Presentation/ViewModels/Pages/ScottPlotPageViewModel.cs - ViewModel
    • AuroraDesk.Presentation/Views/Pages/ScottPlotPageView.axaml - 视图 XAML
    • AuroraDesk.Presentation/Views/Pages/ScottPlotPageView.axaml.cs - 视图代码后台
    • AuroraDesk.Presentation/Services/PageViewModelFactory.cs - 页面工厂注册
    • AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs - ViewModel 注册
    • AuroraDesk.Infrastructure/Services/NavigationService.cs - 导航服务
  • 技术特点:
    • 使用 ReactiveUI + MVVM 模式
    • 支持多种图表类型(散点图、折线图、柱状图等)
    • 支持图表标题和坐标轴标签自定义
    • 现代化的界面设计,操作简单直观
  • 效果:
    • 可以在导航栏中访问"ScottPlot 图表"页面
    • 支持创建多种类型的示例图表
    • 图表展示清晰,交互流畅

新增 LiveCharts2 图表页面

  • 日期: 2025年1月

  • 功能描述: 添加了基于 LiveCharts2 (LiveChartsCore.SkiaSharpView.Avalonia) 的图表展示页面,支持多种图表类型

  • 实现内容:

    1. NuGet 包安装:
      • AuroraDesk.Presentation.csproj 中添加 LiveChartsCore.SkiaSharpView.Avalonia 包引用(版本 2.0.0-rc2)
    2. ViewModel 层:
      • 创建 LiveCharts2PageViewModel,继承自 RoutableViewModel
      • 实现 SeriesXAxesYAxes 集合属性,用于绑定图表数据
      • 提供多种图表创建方法:折线图、柱状图、饼图、面积图
      • 使用 ReactiveCommand 实现命令绑定
      • 支持图表清除功能
    3. View 层:
      • 创建 LiveCharts2PageView.axaml,包含控制面板和图表展示区域
      • 控制面板提供多个操作按钮:折线图、柱状图、饼图、面积图、清除
      • 使用 CartesianChart 控件展示折线图、柱状图、面积图
      • 使用 PieChart 控件展示饼图
      • 在代码后台中根据图表类型自动切换显示 CartesianChartPieChart
      • 使用 WhenAnyValue 监听 Series 变化,自动判断图表类型
    4. 服务注册:
      • PageViewModelFactory 中注册 livecharts2 页面 ID
      • ServiceCollectionExtensions 中注册 LiveCharts2PageViewModel
      • NavigationService 中添加"LiveCharts2 图表"导航项,使用 IconType.ChartPie 图标
  • 涉及文件:

    • AuroraDesk.Presentation/AuroraDesk.Presentation.csproj - 添加 LiveChartsCore.SkiaSharpView.Avalonia 包
    • AuroraDesk.Presentation/ViewModels/Pages/LiveCharts2PageViewModel.cs - ViewModel
    • AuroraDesk.Presentation/Views/Pages/LiveCharts2PageView.axaml - 视图 XAML
    • AuroraDesk.Presentation/Views/Pages/LiveCharts2PageView.axaml.cs - 视图代码后台
    • AuroraDesk.Presentation/Services/PageViewModelFactory.cs - 页面工厂注册
    • AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs - ViewModel 注册
    • AuroraDesk.Infrastructure/Services/NavigationService.cs - 导航服务
  • 技术特点:

    • 使用 ReactiveUI + MVVM 模式
    • 支持多种图表类型(折线图、柱状图、饼图、面积图)
    • 自动根据图表类型切换控件(CartesianChart 或 PieChart)
    • 支持图表缩放和平移(ZoomMode="Pan")
    • 现代化的界面设计,操作简单直观
  • 效果:

    • 可以在导航栏中访问"LiveCharts2 图表"页面
    • 支持创建多种类型的示例图表
    • 图表展示清晰,交互流畅
    • 饼图和其他图表类型自动切换显示
  • 日期: 2025年1月(修复)

  • 问题: LiveCharts2 图表显示空白,没有任何内容

  • 修复内容:

    1. ViewModel 绑定问题修复(关键修复):
      • 将所有方法中直接修改 ObservableCollection 的操作(Clear、Add)改为创建新的 ObservableCollection 并赋值给属性
      • 这样可以确保触发 RaiseAndSetIfChanged,从而触发属性变化通知,让 UI 正确更新
      • 修复 CreateLineChartCreateColumnChartCreateAreaChartCreatePieChartClearChart 方法
      • 修复构造函数初始化,使用属性而不是私有字段,确保绑定正确触发
    2. 轴初始化问题修复:
      • 修复 ClearChart 方法,清除图表后保留默认轴,避免 CartesianChart 无法显示
      • 饼图保持默认轴,避免绑定问题
    3. XAML 布局优化:
      • CartesianChartPieChart 添加 HorizontalAlignment="Stretch"VerticalAlignment="Stretch" 属性
      • 确保图表控件能正确填充可用空间
    4. 代码后台优化:
      • LiveCharts2PageView.axaml.cs 中添加调试输出,便于排查问题
      • 移除了不存在的 Update 方法调用(LiveCharts2 Avalonia 版本没有此方法)
      • 通过创建新集合触发属性变化通知,图表会自动更新
  • 涉及文件:

    • AuroraDesk.Presentation/ViewModels/Pages/LiveCharts2PageViewModel.cs - 修复绑定问题(创建新集合而不是修改现有集合)
    • AuroraDesk.Presentation/Views/Pages/LiveCharts2PageView.axaml - 优化布局属性
    • AuroraDesk.Presentation/Views/Pages/LiveCharts2PageView.axaml.cs - 添加图表强制刷新逻辑
  • 技术细节:

    • 关键问题: 直接修改 ObservableCollection 的内容(如 Clear()Add())不会触发属性的 setter,因此不会触发 RaiseAndSetIfChanged,UI 无法收到更新通知
    • 解决方案: 创建新的 ObservableCollection 并赋值给属性,这样会触发属性变化通知,图表会自动更新
    • CartesianChart 需要至少一个 XAxis 和 YAxis 才能正常显示
    • 图表控件需要明确的对齐方式才能正确填充空间
    • 修复可空性警告:使用 null! 初始化私有字段

重构 LiveCharts2 图表页面(修复数据渲染问题)

  • 日期: 2025年1月
  • 问题描述: LiveCharts2 图表页面始终无法在界面上渲染数据
  • 重构内容:
    1. ViewModel 层重构:
      • XAxesYAxes 的类型从 ObservableCollection<Axis> 改为 ObservableCollection<ICartesianAxis>,确保类型正确
      • 添加 IsPieChart 属性,用于标识当前是否为饼图类型
      • 优化数据更新方式:使用 Clear()Add() 方法直接修改集合,而不是创建新集合(LiveCharts2 支持集合变化通知)
      • 修复饼图数据格式:饼图需要为每个数据点创建一个独立的 PieSeries,而不是一个 PieSeries 包含多个值
      • 完善图表系列配置:为折线图添加 GeometryStrokeGeometryFill 属性,为柱状图添加 Stroke 属性
      • 统一轴配置:所有轴使用 DarkGray 颜色和 TextSize = 12,提升视觉效果
    2. View 层重构:
      • 简化代码后台:移除复杂的手动切换逻辑,改为使用 IsPieChart 属性绑定
      • 使用 InvertedBoolConverter 转换器控制 CartesianChart 的显示/隐藏
      • 直接绑定 IsPieChart 属性控制 PieChart 的显示/隐藏
      • 将图表背景设置为 Transparent,避免与容器背景冲突
      • 添加 AnimationsSpeed 属性,使图表切换更流畅
    3. 数据绑定优化:
      • 确保所有图表类型都正确初始化轴配置
      • 饼图不再需要轴配置,但保持默认轴避免绑定错误
      • 使用 ObservableCollection 的集合变化通知机制,确保图表实时更新
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/LiveCharts2PageViewModel.cs - 重构数据绑定和图表创建逻辑
    • AuroraDesk.Presentation/Views/Pages/LiveCharts2PageView.axaml - 优化图表控件绑定和布局
    • AuroraDesk.Presentation/Views/Pages/LiveCharts2PageView.axaml.cs - 简化代码后台逻辑
  • 技术要点:
    • LiveCharts2 的 ObservableCollection 支持集合变化通知(CollectionChanged 事件),可以直接使用 Clear()Add() 方法
    • 饼图数据格式:每个 PieSeries 代表一个数据点,需要为每个数据点创建独立的系列
    • 使用 ICartesianAxis 接口类型确保类型安全
    • 通过 IsPieChart 属性统一管理图表类型切换,简化代码逻辑
    • 使用转换器实现布尔值取反,避免在 ViewModel 中维护额外的属性

修复 LiveCharts2 SkiaSharp 兼容性问题

  • 日期: 2025年1月
  • 问题描述: 运行时错误 Could not load type 'CropRect' from assembly 'SkiaSharp',导致图表无法初始化
  • 问题原因: LiveCharts2 2.0.0-rc2 版本与较新的 SkiaSharp 版本(3.119.0.0)不兼容,CropRect 类型在较新的 SkiaSharp 版本中已被移除或更改
  • 解决方案:
    • LiveChartsCore.SkiaSharpView.Avalonia2.0.0-rc2 升级到 2.0.0-rc5.1
    • 新版本修复了与 SkiaSharp 的兼容性问题,支持较新的 SkiaSharp 版本
  • 涉及文件:
    • AuroraDesk.Presentation/AuroraDesk.Presentation.csproj - 更新 LiveCharts2 包版本
  • 技术要点:
    • LiveCharts2 2.0.0-rc5.1 版本修复了与 SkiaSharp 3.x 版本的兼容性问题
    • 升级后自动引入了兼容的依赖项(SkiaSharp.HarfBuzz 2.88.9、HarfBuzzSharp 7.3.0.3)
    • 无需修改代码,仅需升级包版本即可解决兼容性问题

修复 LiveCharts2 饼图类型转换错误

  • 日期: 2025年1月
  • 问题描述: 运行时错误 Unable to cast object of type 'LineSeries' to type 'IPieSeries',导致应用程序崩溃
  • 问题原因: CartesianChartPieChart 两个控件都绑定到同一个 Series 集合,即使 PieChartIsVisible = false,它仍然会尝试处理 Series 数据,导致类型转换错误
  • 解决方案:
    • 在 ViewModel 中添加独立的 PieSeries 属性,专门用于饼图数据
    • PieChartSeries 绑定改为绑定到 PieSeries 而不是 Series
    • 在创建非饼图类型时,清空 PieSeries 集合
    • 在创建饼图时,将数据添加到 PieSeries 集合,并清空 Series 集合
    • 修复轴类型:将 ICartesianAxis 改回 Axis(新版本 LiveCharts2 中 ICartesianAxis 接口不存在)
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/LiveCharts2PageViewModel.cs - 添加 PieSeries 属性,修复轴类型
    • AuroraDesk.Presentation/Views/Pages/LiveCharts2PageView.axaml - 修改 PieChartSeries 绑定
  • 技术要点:
    • 不同类型的图表控件应该使用独立的 Series 集合,避免类型冲突
    • LiveCharts2 2.0.0-rc5.1 版本中轴类型应使用 Axis 而不是 ICartesianAxis
    • 即使控件不可见,如果绑定了数据,控件仍可能尝试处理数据,导致类型错误

修复 LiveCharts2 饼图类型转换错误(CastIterator)

  • 日期: 2025年1月
  • 问题描述: 运行时错误发生在 System.Linq.Enumerable.<CastIterator>d__751.MoveNext(),在 LiveChartsCore.PieChartEngine.Measure()` 中,导致应用程序崩溃
  • 问题原因: 在 CreatePieChart 方法中,直接修改 PieSeries 集合(使用 Clear()Add())可能导致类型转换错误,因为 LiveCharts2 在尝试将 ISeries 转换为 IPieSeries 时,集合可能处于不一致的状态
  • 解决方案:
    • CreatePieChart 方法中,创建新的 ObservableCollection<ISeries> 集合并赋值给 PieSeries 属性,而不是直接修改现有集合
    • 这样可以确保触发属性变化通知,并且避免类型转换错误
    • 先清空 Series 集合,确保 CartesianChart 不会尝试处理饼图数据
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/LiveCharts2PageViewModel.cs - 修复 CreatePieChart 方法,使用新集合并赋值
  • 技术要点:
    • 使用属性赋值而不是直接修改集合,可以确保触发属性变化通知
    • 创建新集合可以避免类型转换时的状态不一致问题
    • 确保在创建饼图时,Series 集合被清空,避免 CartesianChart 尝试处理饼图数据

修复 Linux 发布时 SkiaSharp 版本不兼容问题

  • 日期: 2025年1月
  • 问题描述: 在 Linux 上运行应用程序时出现 System.TypeInitializationException 异常,错误信息显示:The version of the native libSkiaSharp library (88.1) is incompatible with this version of SkiaSharp. Supported versions of the native libSkiaSharp library are in the range [119.0, 120.0).
  • 问题原因: Linux 系统上安装的旧版本 libSkiaSharp (88.1) 被优先加载,而应用程序需要 119.0-120.0 版本的本地库。尽管项目已通过 Avalonia 传递依赖引用 SkiaSharp 3.119.0,但发布时可能未正确包含对应的本地库,导致运行时使用了系统的旧版本。
  • 解决方案:
    • 在主项目文件中显式添加 SkiaSharp 包引用(版本 3.119.0),确保版本明确
    • 添加 SkiaSharp.NativeAssets.Linux.NoDependencies 包(版本 3.119.0),确保发布时包含正确的 libSkiaSharp.so 本地库
    • 使用 NoDependencies 版本可以避免额外的系统依赖,应用程序自带所需的本地库
  • 涉及文件:
    • AuroraDesk/AuroraDesk.csproj - 添加 SkiaSharp 和 SkiaSharp.NativeAssets.Linux.NoDependencies 包引用
  • 技术要点:
    • SkiaSharp 3.119.0 版本需要本地库版本 119.0-120.0 范围
    • 使用 SkiaSharp.NativeAssets.Linux.NoDependencies 包确保应用程序自带本地库,不依赖系统安装的版本
    • 自包含发布时,.NET 运行时会优先使用发布目录中的本地库
    • 显式引用包可以确保版本一致性,避免依赖传递导致的版本不匹配问题
  • 测试建议:
    • 重新发布到 Linux(使用 dotnet publish -c Release -r linux-x64 --self-contained true
    • 检查发布目录中是否包含 libSkiaSharp.so 文件(通常在 runtimes/linux-x64/native/ 目录下)
    • 在 Linux 系统上运行应用程序,验证不再出现版本不兼容错误

修复 LiveCharts2 折线图逐个点渲染和布局问题

  • 日期: 2025年1月
  • 问题描述:
    1. 底部有空白区域(三行布局导致)
    2. 折线图启动时不是逐个点渲染,而是所有点同时显示
  • 修复内容:
    1. 布局修复:
      • 将布局从三行两列改为两行两列,移除底部空白
      • 调整第二行图表的 Margin,移除底部边距
    2. 逐个点渲染修复:
      • 修改 UpdateLineChartData() 方法,添加 pointCount 逻辑
      • 如果正在运行,只显示到 _currentDataIndex 的点(已更新的点)
      • 确保两个系列(系列1和系列2)同步逐个点更新
      • Start 时清除数据并清空图表,从空状态开始
      • 每个点间隔1秒逐个添加,实现累计渲染效果
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/LiveCharts2PageViewModel.cs - 修复逐个点渲染逻辑
    • AuroraDesk.Presentation/Views/Pages/LiveCharts2PageView.axaml - 改为两行两列布局
  • 技术要点:
    • 使用 _currentDataIndex 跟踪当前更新的数据点
    • UpdateLineChartData() 中根据运行状态决定显示的点数
    • 两个系列的数据同步更新,确保折线图正确显示
    • 使用 Array.Resize 动态扩展数组,避免重置索引导致的数据丢失
    • 数据点持续累积,实现真正的实时数据流效果
    • 保持系列对象引用,直接更新 Values 集合,避免重新创建整个系列集合
    • 实现平滑的叠加动画效果,而不是整个图表刷新
    • 实现滑动窗口机制,只显示最近50个数据点,x坐标从0开始重新编号
    • 避免图表因数据点过多而变得混乱,保持图表清晰可读
      • 滑动窗口优化
        • 添加 MaxDisplayPoints = 50 常量,限制最大显示点数
        • 当数据点超过50个时,只显示最近50个点(滑动窗口)
        • x坐标从0开始重新编号,确保不会出现负数
        • 避免图表因数据点过多而变得混乱,保持图表清晰可读
        • 数据仍然持续累积,但显示时只显示最近的数据点

重构 ScottPlot 页面为两行两列布局并添加实时推送和阈值颜色功能

  • 日期: 2025年1月
  • 修改内容: 将 ScottPlot 页面重构为两行两列布局,同时显示4种不同类型的图表,为示例图表添加 Start/Stop 实时推送控制和阈值颜色标色功能
  • 布局结构:
    • 第一行第一列:示例图表
    • 第一行第二列:正弦波
    • 第二行第一列:多系列图表
    • 第二行第二列:柱状图
  • ViewModel 重构:
    • 将单个 PlotControl 改为4个独立的图表控件引用:
      • PlotControl1(示例图表)
      • PlotControl2(正弦波)
      • PlotControl3(多系列)
      • PlotControl4(柱状图)
    • 将创建方法改为初始化方法(InitializeChart1InitializeChart2 等)
    • 当图表控件被设置时,自动调用对应的初始化方法
    • 保留原有的创建方法作为兼容性方法
    • ClearChart 方法现在清除所有4个图表
  • View 重构:
    • 移除控制面板和所有按钮
    • 使用两行两列的 Grid 布局
    • 每个图表使用独立的 Border 容器,包含标题和图表控件
    • 每个图表区域都有独立的标题("示例图表"、"正弦波"、"多系列图表"、"柱状图")
    • 图表之间使用 Margin 保持间距(6px)
  • View Code-Behind 重构:
    • 更新 ScottPlotPageView.axaml.cs,查找并绑定4个独立的图表控件
    • WhenActivated 中设置所有图表控件的引用
    • 在清理时清空所有图表控件的引用
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/ScottPlotPageViewModel.cs - 重构为4个独立的图表控件和初始化方法
    • AuroraDesk.Presentation/Views/Pages/ScottPlotPageView.axaml - 改为两行两列布局,移除控制面板
    • AuroraDesk.Presentation/Views/Pages/ScottPlotPageView.axaml.cs - 更新为绑定4个图表控件
  • 示例图表实时推送功能:
    • 添加 IsLineChartRunning 属性:标识图表是否正在刷新
    • 添加 Threshold 属性:阈值配置(默认 7.0),可动态调整
    • 添加 StartLineChartCommand:开始刷新命令
      • 点击 Start 时清除数据,开始实时推送
      • 启动后台任务,每秒生成随机数据并更新图表
    • 添加 StopLineChartCommand:停止刷新命令
      • 点击 Stop 时停止后台任务
      • 保持当前数据状态,不恢复默认数据
    • 添加 ResetLineChartCommand:重置命令
      • 点击刷新按钮时清除数据
      • 如果正在运行,先停止刷新任务
    • 实现 UpdateLineChartData() 方法:
      • 使用滑动窗口机制,只显示最近50个数据点
      • x坐标从0开始重新编号,确保不会出现负数
      • 根据阈值设置颜色:
        • 超过阈值的点:绿色(MarkerSize=10)
        • 正常点:蓝色(MarkerSize=8)
      • 使用折线连接所有点,使用散点显示不同颜色的点
  • 技术要点:
    • 每个图表类型使用独立的控件引用,避免冲突
    • 页面加载时自动初始化所有图表,无需用户操作
    • 两行两列布局充分利用屏幕空间,同时展示所有图表类型
    • 每个图表区域都有清晰的标题,便于识别
    • 图表控件通过属性设置器自动触发初始化,实现自动加载
    • 使用 CancellationTokenSource 管理后台任务生命周期
    • 使用 Task.Run 在后台线程生成数据
    • 使用 Dispatcher.UIThread.Post 在 UI 线程更新图表
    • 实现滑动窗口机制,避免图表因数据点过多而变得混乱

重构 LiveCharts2 页面为三行两列布局并添加折线图控制功能

  • 日期: 2025年1月
  • 修改内容: 将 LiveCharts2 页面改为三行两列布局,同时显示4种不同类型的图表,为折线图添加 Start/Stop 控制和阈值配置功能
  • 布局结构:
    • 第一行第一列:折线图(CartesianChart,带控制面板)
    • 第一行第二列:柱状图(CartesianChart)
    • 第二行第一列:饼图(PieChart)
    • 第二行第二列:面积图(CartesianChart)
    • 第三行:预留空间(当前为空)
  • ViewModel 重构:
    • 为每种图表类型添加独立的 Series 和 Axes 集合:
      • LineSeriesLineXAxesLineYAxes(折线图)
      • ColumnSeriesColumnXAxesColumnYAxes(柱状图)
      • PieSeries(饼图)
      • AreaSeriesAreaXAxesAreaYAxes(面积图)
    • 移除所有创建命令(CreateLineChartCommandCreateColumnChartCommand 等)
    • 将创建方法改为初始化方法(InitializeLineChartInitializeColumnChart 等)
    • 在构造函数中自动初始化所有4个图表
    • 折线图控制功能:
      • 添加 IsLineChartRunning 属性:标识折线图是否正在刷新
      • 添加 Threshold 属性:阈值配置(默认 7.0),可动态调整
      • 添加 StartLineChartCommand:开始刷新命令
        • 点击 Start 时清除折线图默认数据(初始化为空数组)
        • 启动后台任务,每秒生成随机数据并实时推送更新图表
        • 实现实时数据流效果
      • 添加 StopLineChartCommand:停止刷新命令
        • 点击 Stop 时停止后台任务
        • 保持当前数据状态,不恢复默认数据
      • 添加 ResetLineChartCommand:重置命令
        • 点击刷新按钮时恢复原始默认数据
        • 如果正在运行,先停止刷新任务
      • 实现 UpdateLineChartData() 方法:
        • 使用 ObservablePoint 保持点的位置关系
        • 使用 LineSeries 显示折线
        • 使用 ScatterSeries 显示点,根据阈值设置颜色:
          • 超过阈值的点:绿色(GeometrySize=10)
          • 正常点:蓝色/红色(GeometrySize=8,根据系列)
        • 保持两个系列(系列1蓝色,系列2红色)
  • View 重构:
    • 使用两行两列的 Grid 布局(移除底部空白)
    • 每个图表使用独立的 Border 容器,包含标题和图表控件
    • 每个图表区域都有独立的标题("折线图"、"柱状图"、"饼图"、"面积图")
    • 图表之间使用 Margin 保持间距(6px)
      • 折线图控制面板:
        • 在折线图区域添加控制面板(阈值输入、Start/Stop/刷新 按钮)
        • 阈值输入:使用 NumericUpDown 控件,范围 0-20,步进 0.5
        • Start 按钮:绿色背景,仅在未运行时启用
        • Stop 按钮:红色背景,仅在运行时启用
        • 刷新按钮:蓝色背景,用于恢复默认数据
        • 使用 InvertedBoolConverter 实现按钮启用状态的逻辑反转
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/LiveCharts2PageViewModel.cs - 重构为4个独立的图表集合和初始化方法
    • AuroraDesk.Presentation/Views/Pages/LiveCharts2PageView.axaml - 改为两行两列布局,移除按钮
  • 技术要点:
    • 每个图表类型使用独立的集合,避免类型冲突
    • 页面加载时自动初始化所有图表,无需用户操作
    • 两行两列布局充分利用屏幕空间,同时展示所有图表类型,无底部空白
    • 每个图表区域都有清晰的标题,便于识别
    • 折线图实时刷新:
      • 使用 CancellationTokenSource 管理后台任务生命周期
      • 使用 Task.Run 在后台线程生成数据
      • 使用 Dispatcher.UIThread.Post 在 UI 线程更新图表
      • 每秒刷新一次数据,模拟实时数据流
      • Start 时清除数据并开始实时推送,Stop 时停止推送但保持数据,刷新时恢复默认数据
      • 逐个点渲染:Start 时从第一个点开始,每个点间隔1秒逐个添加,实现累计效果
      • 使用 _currentDataIndex 字段跟踪当前更新的数据点索引
      • UpdateLineChartData() 中,如果正在运行,只显示到 _currentDataIndex 的点(已更新的点)
      • 确保两个系列(系列1和系列2)同步逐个点更新
      • 当索引超出数组长度时,使用 Array.Resize 扩展数组(每次增加10个点),而不是重置索引
      • 数据点持续累积,不会被重置,实现真正的实时数据流效果
      • Start 时清除数据并清空图表,从空状态开始逐个点渲染
      • 优化叠加效果
        • 保持系列对象的引用,而不是每次更新都重新创建整个系列集合
        • 直接更新 Values 集合(ObservableCollection<ObservablePoint>),实现平滑的叠加效果
        • 使用 CreateLineSeries() 方法创建系列,UpdateLineChartData() 只更新数据
        • 避免整个图表重新渲染,实现真正的叠加动画效果
      • 阈值颜色区分:
        • 使用 LineSeries<ObservablePoint> 显示折线,保持点的位置关系
        • 使用 ScatterSeries<ObservablePoint> 显示点,支持不同颜色
        • 超过阈值的点显示为绿色,正常点显示为蓝色/红色
        • 阈值改变时自动更新图表颜色

新增表单示例页面

  • 日期: 2025年1月
  • 功能描述: 添加了表单示例页面,包含按钮点击弹出表单对话框功能
  • 实现内容:
    1. ViewModel 层:
      • 创建 FormPageViewModel,继承自 RoutableViewModel
      • 实现表单字段属性:姓名、邮箱、电话、地址、备注
      • 实现表单对话框显示/隐藏控制:IsFormDialogOpen
      • 提供表单提交和取消命令:ShowFormCommandSubmitFormCommandCancelFormCommand
      • 实现表单验证逻辑:必填字段检查、邮箱格式验证
      • 显示提交结果信息
    2. View 层:
      • 创建 FormPageView.axaml,使用 DialogHost 实现弹出表单
      • 主界面包含"打开表单"按钮和结果显示区域
      • 表单对话框包含:
        • 标题区域(带图标)
        • 表单字段:姓名(必填)、邮箱(必填)、电话(可选)、地址(可选)、备注(可选)
        • 错误提示区域(动态显示验证错误)
        • 提交和取消按钮
      • 表单支持滚动,适配长内容
    3. 转换器扩展:
      • StringConverters 中新增 IsNotNullOrEmptyConverter 转换器
      • 用于检查字符串是否非空,控制错误提示区域的显示
    4. 服务注册:
      • PageViewModelFactory 中注册 form 页面 ID
      • ServiceCollectionExtensions 中注册 FormPageViewModel
      • NavigationService 中添加"表单示例"导航项,使用 IconType.DocumentText 图标
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/FormPageViewModel.cs - ViewModel
    • AuroraDesk.Presentation/Views/Pages/FormPageView.axaml - 视图 XAML
    • AuroraDesk.Presentation/Views/Pages/FormPageView.axaml.cs - 视图代码后台
    • AuroraDesk.Presentation/Converters/StringConverters.cs - 新增转换器
    • AuroraDesk.Presentation/Services/PageViewModelFactory.cs - 页面工厂注册
    • AuroraDesk.Presentation/Extensions/ServiceCollectionExtensions.cs - ViewModel 注册
    • AuroraDesk.Infrastructure/Services/NavigationService.cs - 导航服务
  • 技术特点:
    • 使用 ReactiveUI + MVVM 模式
    • 使用 DialogHost.Avalonia 实现模态对话框
    • 支持表单验证和错误提示
    • 现代化的界面设计,表单布局清晰
    • 支持必填字段和可选字段
    • 提交结果显示在主界面
  • 效果:
    • 可以在导航栏中访问"表单示例"页面
    • 点击"打开表单"按钮弹出表单对话框
    • 填写表单信息并提交,支持验证
    • 提交结果显示在主界面
    • 表单界面美观,交互流畅

扩展表单示例页面 - 支持多种表单形态

  • 日期: 2025年1月
  • 功能描述: 扩展表单页面,添加多个按钮,每个按钮对应不同的表单形态
  • 实现内容:
    1. 表单类型枚举:
      • 新增 FormType 枚举,定义5种表单类型:
        • Basic: 基础表单(全字段:姓名、邮箱、电话、地址、备注)
        • Simple: 简洁表单(仅姓名、邮箱)
        • Contact: 联系表单(姓名、电话、邮箱)
        • Feedback: 反馈表单(姓名、邮箱、备注)
        • Register: 注册表单(姓名、邮箱、电话、地址)
    2. ViewModel 扩展:
      • 添加 CurrentFormType 属性,标识当前表单类型
      • 添加 FormTitleFormDescription 属性,动态显示表单标题和描述
      • 添加字段可见性属性:ShowPhoneFieldShowAddressFieldShowRemarksField
      • 添加5个不同的命令:ShowBasicFormCommandShowSimpleFormCommandShowContactFormCommandShowFeedbackFormCommandShowRegisterFormCommand
      • 根据表单类型动态设置标题、描述和字段可见性
      • 根据表单类型进行不同的验证规则
    3. View 扩展:
      • 添加5个不同颜色的按钮,每个按钮对应一种表单类型
      • 按钮颜色区分:基础表单(蓝色)、简洁表单(绿色)、联系表单(紫色)、反馈表单(橙色)、注册表单(红色)
      • 表单字段根据 IsVisible 绑定动态显示/隐藏
      • 表单标题和描述绑定到 ViewModel 属性,动态更新
    4. 验证逻辑优化:
      • 基础表单:验证姓名和邮箱
      • 简洁表单:验证姓名和邮箱
      • 联系表单:验证姓名、邮箱和电话
      • 反馈表单:验证姓名、邮箱和备注
      • 注册表单:验证姓名、邮箱、电话和地址
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/FormPageViewModel.cs - 扩展 ViewModel,添加表单类型和多个命令
    • AuroraDesk.Presentation/Views/Pages/FormPageView.axaml - 添加多个按钮,动态显示字段
  • 技术特点:
    • 使用枚举定义表单类型,类型安全
    • 根据表单类型动态显示/隐藏字段
    • 不同表单类型使用不同的验证规则
    • 按钮使用不同颜色区分,视觉清晰
    • 表单标题和描述动态更新
  • 效果:
    • 提供5种不同的表单形态,满足不同场景需求
    • 点击不同按钮打开对应类型的表单
    • 表单字段根据类型动态显示,界面简洁
    • 每种表单类型有独立的验证规则
    • 提交结果显示表单类型,便于区分

重构表单示例页面 - 实现不同布局形态和控件类型

  • 日期: 2025年1月
  • 功能描述: 重构表单页面,为不同表单类型设计不同的布局形态和控件组合,使每种表单在视觉和功能上都有明显区别
  • 实现内容:
    1. 布局形态设计:
      • 基础表单:垂直布局(标签在上,输入框在下),包含所有字段
      • 简洁表单:水平布局(标签和输入框在同一行,使用 Grid 两列),仅包含姓名和邮箱
      • 联系表单:垂直布局,包含下拉框(ComboBox)选择国家和城市
      • 反馈表单:垂直布局,包含复选框(CheckBox)选项
      • 注册表单:两列布局(使用 Grid 两列两行),充分利用空间
    2. 新增控件类型:
      • 下拉框(ComboBox):用于联系表单,选择国家和城市
      • 复选框(CheckBox):用于反馈表单,包含"同意条款"、"订阅邮件"、"接收通知"等选项
    3. ViewModel 扩展:
      • 添加布局控制属性:UseHorizontalLayoutUseTwoColumnLayout
      • 添加控件显示属性:ShowComboBoxFieldsShowCheckBoxFields
      • 添加下拉框数据:CountriesCitiesSelectedCountrySelectedCity
      • 添加复选框数据:AgreeTermsSubscribeNewsletterReceiveNotifications
      • 根据表单类型进行不同的验证规则(包括下拉框和复选框验证)
    4. 转换器扩展:
      • 新增 BoolToVisibilityConverter 转换器,支持布尔值到可见性转换
      • 支持反转参数(ConverterParameter='Invert'),用于条件显示
    5. XAML 布局重构:
      • 使用条件显示(IsVisible 绑定)实现不同布局
      • 基础表单:垂直 StackPanel 布局
      • 简洁表单:Grid 水平布局(标签列宽 100,输入框自适应)
      • 注册表单:Grid 两列两行布局
      • 联系表单:在垂直布局中添加 ComboBox
      • 反馈表单:在垂直布局中添加 CheckBox
  • 涉及文件:
    • AuroraDesk.Presentation/ViewModels/Pages/FormPageViewModel.cs - 扩展 ViewModel,添加布局控制和控件数据
    • AuroraDesk.Presentation/Views/Pages/FormPageView.axaml - 重构布局,实现不同表单形态
    • AuroraDesk.Presentation/Converters/StringConverters.cs - 新增 BoolToVisibilityConverter
  • 技术特点:
    • 5种不同的布局形态,视觉差异明显
    • 使用 Grid 实现水平布局和两列布局
    • 使用 ComboBox 和 CheckBox 丰富表单控件类型
    • 条件显示实现布局切换,代码清晰
    • 每种表单类型有独特的布局和控件组合
  • 效果:
    • 基础表单:传统垂直布局,标签在上输入框在下
    • 简洁表单:水平布局,标签和输入框在同一行,节省空间
    • 联系表单:包含下拉框选择,交互更友好
    • 反馈表单:包含复选框选项,支持多选
    • 注册表单:两列布局,充分利用横向空间
    • 每种表单形态在视觉和功能上都有明显区别