using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using PersonalToolBox.Helpers; using PersonalToolBox.Models; using PersonalToolBox.Services; namespace PersonalToolBox.ViewModels; /// /// 组合编辑窗口 ViewModel,管理一键多开组合的创建与编辑 /// public partial class GroupEditViewModel : ObservableObject { private readonly IDataService _dataService; private readonly ILogService _logService; private readonly ToolItem? _editingGroup; // ──────── 可观察属性 ──────── [ObservableProperty] private string _windowTitle = "添加组合"; [ObservableProperty] private string _name = string.Empty; [ObservableProperty] private string _hotKey = string.Empty; [ObservableProperty] private Category? _selectedCategory; [ObservableProperty] private IconProvider.IconOption? _selectedIcon; [ObservableProperty] private bool _autoRunOnStart; /// /// 可供勾选的普通工具列表(IsGroup == false) /// public ObservableCollection AvailableTools { get; } = new(); /// /// 分类下拉列表 /// public ObservableCollection Categories { get; } = new(); /// /// 按分类分组的可用图标列表 /// public ListCollectionView AvailableIconsView { get; } public Action? CloseAction { get; set; } public bool Saved { get; private set; } // ──────── 构造 ──────── public GroupEditViewModel(IDataService dataService, ILogService logService, ToolItem? groupToEdit = null) { _dataService = dataService; _logService = logService; _editingGroup = groupToEdit; AvailableIconsView = new ListCollectionView(IconProvider.AvailableIcons); AvailableIconsView.GroupDescriptions.Add(new PropertyGroupDescription("Category")); foreach (var cat in _dataService.Config.Categories) Categories.Add(cat); // 加载所有工具(排除自身及祖先组合,防止循环引用) var excludeIds = GetAncestorIds(); var selectedIds = _editingGroup?.SubToolIds ?? new List(); foreach (var tool in _dataService.Config.Tools.Where(t => !excludeIds.Contains(t.Id))) { AvailableTools.Add(new SelectableTool { Tool = tool, IsSelected = selectedIds.Contains(tool.Id) }); } if (groupToEdit != null) { WindowTitle = "编辑组合"; Name = groupToEdit.Name; HotKey = groupToEdit.HotKey; SelectedCategory = Categories.FirstOrDefault(c => c.Id == groupToEdit.CategoryId); AutoRunOnStart = groupToEdit.AutoRunOnStart; if (!string.IsNullOrEmpty(groupToEdit.IconCode)) { SelectedIcon = IconProvider.AvailableIcons.FirstOrDefault(i => i.Icon.ToString() == groupToEdit.IconCode); } } } // ──────── 命令 ──────── [RelayCommand] private void Save() { try { if (string.IsNullOrWhiteSpace(Name)) { _logService.Warning("组合名称不能为空"); return; } var selectedIds = AvailableTools .Where(t => t.IsSelected) .Select(t => t.Tool.Id) .ToList(); if (_editingGroup != null) { _editingGroup.Name = Name.Trim(); _editingGroup.IconCode = SelectedIcon?.Icon.ToString() ?? string.Empty; _editingGroup.HotKey = HotKey.Trim(); _editingGroup.CategoryId = SelectedCategory?.Id ?? string.Empty; _editingGroup.SubToolIds = selectedIds; _editingGroup.IsValid = true; _editingGroup.AutoRunOnStart = AutoRunOnStart; _logService.Info($"已更新组合: {Name.Trim()}(包含 {selectedIds.Count} 个工具)"); } else { _dataService.Config.Tools.Add(new ToolItem { Name = Name.Trim(), IconCode = SelectedIcon?.Icon.ToString() ?? string.Empty, HotKey = HotKey.Trim(), CategoryId = SelectedCategory?.Id ?? string.Empty, IsGroup = true, SubToolIds = selectedIds, IsValid = true, AutoRunOnStart = AutoRunOnStart }); _logService.Info($"已添加组合: {Name.Trim()}(包含 {selectedIds.Count} 个工具)"); } _dataService.Save(); Saved = true; CloseAction?.Invoke(true); } catch (Exception ex) { _logService.Error($"保存组合失败: {ex.Message}"); } } [RelayCommand] private void Cancel() { CloseAction?.Invoke(false); } /// /// 获取需要排除的工具 ID 集合(自身 + 所有祖先组合),防止循环引用 /// private System.Collections.Generic.HashSet GetAncestorIds() { var ancestors = new System.Collections.Generic.HashSet(); if (_editingGroup != null) { ancestors.Add(_editingGroup.Id); CollectAncestors(_editingGroup.Id, ancestors); } return ancestors; } private void CollectAncestors(string groupId, System.Collections.Generic.HashSet ancestors) { foreach (var tool in _dataService.Config.Tools.Where(t => t.IsGroup)) { if (tool.SubToolIds.Contains(groupId) && ancestors.Add(tool.Id)) { CollectAncestors(tool.Id, ancestors); } } } } /// /// 可勾选的工具项(用于 CheckBox 列表绑定) /// public partial class SelectableTool : ObservableObject { public ToolItem Tool { get; set; } = null!; [ObservableProperty] private bool _isSelected; }