From 647d72afab5db70c639633960b16d5f3c5cc99e7 Mon Sep 17 00:00:00 2001 From: ShrlAlgo <903524121@qq.com> Date: Thu, 4 Sep 2025 10:18:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=94=99=E8=AF=AF=E5=92=8C?= =?UTF-8?q?=E4=BA=A4=E4=BA=92=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AddInManager/AddinManager.cs | 95 ++++++++---------------- AddInManager/Wpf/MainWindow.xaml.cs | 111 +++++++++++++++++----------- 2 files changed, 98 insertions(+), 108 deletions(-) diff --git a/AddInManager/AddinManager.cs b/AddInManager/AddinManager.cs index c528f29..a246471 100644 --- a/AddInManager/AddinManager.cs +++ b/AddInManager/AddinManager.cs @@ -1,8 +1,8 @@ - -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Reflection; using AddInManager.Properties; @@ -114,9 +114,9 @@ namespace AddInManager Applications.Save(RevitIniFile); } - public void SaveToLocal() + public void SaveToLocal(AddinType addinTypeToSave) { - SaveToLocalManifest(); + SaveToLocalManifest(addinTypeToSave); } public void SaveToLocalRevitIni() @@ -166,44 +166,37 @@ namespace AddInManager return false; } - public string SaveToAllUserManifest() + public string SaveToAllUserManifest(AddinType addinTypeToSave) { var folderPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); var currentAddinFolder = Path.Combine(folderPath, $"Autodesk\\Revit\\Addins\\{App.RevitVersion}"); var manifestFile = new ManifestFile(false); var numCmdAddins = 0; Addin savedCmdAddin = null; - foreach (var cmdAddin in Commands.AddinDict.Values) + if (addinTypeToSave == AddinType.Command) { - if (cmdAddin.Save) + foreach (var cmdAddin in Commands.AddinDict.Values.Where(a => a.Save)) { numCmdAddins++; savedCmdAddin = cmdAddin; - } - foreach (var addinItem in cmdAddin.ItemList) - { - if (addinItem.Save) + foreach (var addinItem in cmdAddin.ItemList.Where(i => i.Save)) { manifestFile.Commands.Add(addinItem); } } } + var numAppAddins = 0; Addin savedAppAddin = null; - foreach (var appAddin in Applications.AddinDict.Values) + if (addinTypeToSave == AddinType.Application) { - if (appAddin.Save) + foreach (var appAddin in Applications.AddinDict.Values.Where(a => a.Save)) { - numCmdAddins++; + numAppAddins++; savedAppAddin = appAddin; - } - foreach (var appAddinItem in appAddin.ItemList) - { - if (appAddinItem.Save) + foreach (var appAddinItem in appAddin.ItemList.Where(i => i.Save)) { manifestFile.Applications.Add(appAddinItem); - numAppAddins++; - savedAppAddin = appAddin; } } } @@ -236,67 +229,37 @@ namespace AddInManager return addinFilePath; } - public void SaveToLocalManifest() + public void SaveToLocalManifest(AddinType addinTypeToSave) { - var dictionary = new Dictionary(); - var dictionary2 = new Dictionary(); - foreach (var cmdKeyValuePair in Commands.AddinDict) + if (addinTypeToSave == AddinType.Command) { - var key = cmdKeyValuePair.Key; - var value = cmdKeyValuePair.Value; - var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(value.FilePath); - var directoryName = Path.GetDirectoryName(value.FilePath); - var text = Path.Combine(directoryName, $"{fileNameWithoutExtension}.addin"); - var manifestFile = new ManifestFile(true); - foreach (var addinItem in value.ItemList) + foreach (var cmdKeyValuePair in Commands.AddinDict.Where(kv => kv.Value.Save)) { - if (addinItem.Save) + var value = cmdKeyValuePair.Value; + var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(value.FilePath); + var directoryName = Path.GetDirectoryName(value.FilePath); + var text = Path.Combine(directoryName, $"{fileNameWithoutExtension}.addin"); + var manifestFile = new ManifestFile(true); + foreach (var addinItem in value.ItemList.Where(i => i.Save)) { manifestFile.Commands.Add(addinItem); } + manifestFile.SaveAs(text); } - if (Applications.AddinDict.ContainsKey(key)) - { - var addin = Applications.AddinDict[key]; - foreach (var addinItem2 in addin.ItemList) - { - if (addinItem2.Save) - { - manifestFile.Applications.Add(addinItem2); - } - } - dictionary.Add(key, Applications.AddinDict[key]); - } - manifestFile.SaveAs(text); } - foreach (var appKeyValuePair in Applications.AddinDict) + + if (addinTypeToSave == AddinType.Application) { - var key2 = appKeyValuePair.Key; - var value2 = appKeyValuePair.Value; - if (!dictionary.ContainsKey(key2)) + foreach (var appKeyValuePair in Applications.AddinDict.Where(kv => kv.Value.Save)) { + var value2 = appKeyValuePair.Value; var fileNameWithoutExtension2 = Path.GetFileNameWithoutExtension(value2.FilePath); var directoryName2 = Path.GetDirectoryName(value2.FilePath); var text2 = Path.Combine(directoryName2, $"{fileNameWithoutExtension2}.addin"); var manifestFile2 = new ManifestFile(true); - foreach (var addinItem3 in value2.ItemList) + foreach (var addinItem3 in value2.ItemList.Where(i => i.Save)) { - if (addinItem3.Save) - { - manifestFile2.Applications.Add(addinItem3); - } - } - if (Commands.AddinDict.ContainsKey(key2)) - { - var addin2 = Commands.AddinDict[key2]; - foreach (var addinItem4 in addin2.ItemList) - { - if (addinItem4.Save) - { - manifestFile2.Commands.Add(addinItem4); - } - } - dictionary2.Add(key2, Commands.AddinDict[key2]); + manifestFile2.Applications.Add(addinItem3); } manifestFile2.SaveAs(text2); } diff --git a/AddInManager/Wpf/MainWindow.xaml.cs b/AddInManager/Wpf/MainWindow.xaml.cs index 0d61d3b..56ff2ab 100644 --- a/AddInManager/Wpf/MainWindow.xaml.cs +++ b/AddInManager/Wpf/MainWindow.xaml.cs @@ -330,61 +330,70 @@ namespace AddInManager.Wpf private void TreeViewCheckBox_Changed(object sender, RoutedEventArgs e) { - if (sender is CheckBox checkBox) + if (!(sender is CheckBox checkBox)) return; + + var item = FindTreeViewItemFromCheckBox(checkBox); + if (item?.Tag == null) return; + + // 区分是父节点还是子节点 + if (item.Tag is Addin addin) { - var item = FindTreeViewItemFromCheckBox(checkBox); - if (item == null) return; - - var isChecked = checkBox.IsChecked == true; - - // 更新对应的数据模型 - if (item.Tag is Addin addin) + // --- 父节点逻辑 --- + var newState = checkBox.IsChecked; + // 仅当父节点被用户明确点击为“选中”或“未选中”时,才更新所有子节点 + // 如果状态变为 null(不确定),则不执行任何操作,因为它是由子节点更新引起的 + if (newState.HasValue) { + var isChecked = newState.Value; addin.Save = isChecked; - - // 父节点状态变化时,同步更新所有子节点 UpdateChildrenCheckBoxes(item, isChecked); } - else if (item.Tag is AddinItem addinItem) + else { - addinItem.Save = isChecked; - - // 子节点状态变化时,检查是否需要更新父节点状态 - UpdateParentCheckBoxState(item); + // 当状态为不确定时,我们认为它仍然有需要保存的项 + addin.Save = true; } - - // 保存更改 - m_aim.AddinManager.SaveToAimIni(); } + else if (item.Tag is AddinItem addinItem) + { + // --- 子节点逻辑 --- + var isChecked = checkBox.IsChecked == true; + addinItem.Save = isChecked; + // 更新父节点的状态 + UpdateParentCheckBoxState(item); + } + + // 保存更改到配置文件 + m_aim.AddinManager.SaveToAimIni(); } private void UpdateChildrenCheckBoxes(TreeViewItem parentItem, bool isChecked) { + // 遍历所有子项并更新它们的状态 foreach (TreeViewItem childItem in parentItem.Items) { - // 更新子节点CheckBox状态 - var childCheckBox = FindCheckBoxInTreeViewItem(childItem); - if (childCheckBox != null) - { - // 临时移除事件处理,避免递归调用 - childCheckBox.Checked -= TreeViewCheckBox_Changed; - childCheckBox.Unchecked -= TreeViewCheckBox_Changed; - - childCheckBox.IsChecked = isChecked; - - // 重新添加事件处理 - childCheckBox.Checked += TreeViewCheckBox_Changed; - childCheckBox.Unchecked += TreeViewCheckBox_Changed; - } - - // 更新子节点数据模型 if (childItem.Tag is AddinItem addinItem) { + // 更新数据模型 addinItem.Save = isChecked; + + // 更新UI(CheckBox) + var childCheckBox = FindCheckBoxInTreeViewItem(childItem); + if (childCheckBox != null) + { + // 临时移除事件处理程序,防止无限递归 + childCheckBox.Checked -= TreeViewCheckBox_Changed; + childCheckBox.Unchecked -= TreeViewCheckBox_Changed; + + childCheckBox.IsChecked = isChecked; + + // 重新附加事件处理程序 + childCheckBox.Checked += TreeViewCheckBox_Changed; + childCheckBox.Unchecked += TreeViewCheckBox_Changed; + } } } } - private void UpdateParentCheckBoxState(TreeViewItem childItem) { if (childItem.Parent is TreeViewItem parentItem) @@ -443,7 +452,6 @@ namespace AddInManager.Wpf } } } - #endregion private void LoadButton_Click(object sender, RoutedEventArgs e) @@ -831,12 +839,14 @@ namespace AddInManager.Wpf private void CommandsTreeView_MouseDoubleClick(object sender, MouseButtonEventArgs e) { if (e.ChangedButton != MouseButton.Left) return; + // 使用辅助方法 FindTreeViewItem 查找被双击的 TreeViewItem + var clickedItem = FindTreeViewItem(e.OriginalSource as DependencyObject); - var selectedItem = commandsTreeView.SelectedItem as TreeViewItem; - if (selectedItem != null && !HasChildren(selectedItem)) + // 确保双击的是一个有效的 TreeViewItem,并且它是一个子节点(没有子项) + if (clickedItem != null && !HasChildren(clickedItem)) { - // 确保选中的是可执行的命令项 - if (m_aim.ActiveCmdItem != null) + // 确保选中的是可执行的命令项 (AddinItem) + if (clickedItem.Tag is AddinItem) { Run(); } @@ -845,6 +855,21 @@ namespace AddInManager.Wpf ShowStatusError("选中的项目不是可执行的命令"); } } + // 如果双击的是空白区域或父节点,则不执行任何操作 + //var selectedItem = commandsTreeView.SelectedItem as TreeViewItem; + + //if (selectedItem != null && !HasChildren(selectedItem)) + //{ + // // 确保选中的是可执行的命令项 + // if (m_aim.ActiveCmdItem != null) + // { + // Run(); + // } + // else + // { + // ShowStatusError("选中的项目不是可执行的命令"); + // } + //} } private void SaveToAddinMenuItem_Click(object sender, RoutedEventArgs e) @@ -854,7 +879,8 @@ namespace AddInManager.Wpf MessageBox.Show(Properties.Resources.NoItemsSelected, Properties.Resources.AppName, MessageBoxButton.OK, MessageBoxImage.Exclamation); return; } - m_aim.AddinManager.SaveToAllUserManifest(); + var typeToSave = externalToolsTabControl.SelectedItem == commandsTabPage ? AddinType.Command : AddinType.Application; + m_aim.AddinManager.SaveToAllUserManifest(typeToSave); ShowStatusLabel("保存成功,请关闭窗口加载插件"); } @@ -865,7 +891,8 @@ namespace AddInManager.Wpf MessageBox.Show(Properties.Resources.NoItemsSelected, Properties.Resources.AppName, MessageBoxButton.OK, MessageBoxImage.Exclamation); return; } - m_aim.AddinManager.SaveToLocal(); + var typeToSave = externalToolsTabControl.SelectedItem == commandsTabPage ? AddinType.Command : AddinType.Application; + m_aim.AddinManager.SaveToLocal(typeToSave); ShowStatusLabel("保存成功"); }