From 36234cb529d451d33b92c014524cb8afca4ed848 Mon Sep 17 00:00:00 2001 From: GG Z <903524121@qq.com> Date: Thu, 4 Sep 2025 22:39:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AddinManager/AddinManager.csproj | 76 - AddinManager/Services/AddinManagerService.cs | 1501 ----------------- NeoUI/NeoUI/Animations/Animations.xaml | 24 +- NeoUI/NeoUI/Assets/CommonGeometry.xaml | 28 +- NeoUI/NeoUI/Controls/Accordion.xaml | 161 ++ NeoUI/NeoUI/Controls/Accordion.xaml.cs | 99 ++ NeoUI/NeoUI/Controls/AccordionItem.cs | 22 + NeoUI/NeoUI/Controls/Alert.xaml | 23 +- NeoUI/NeoUI/Controls/Anchor.xaml | 11 +- NeoUI/NeoUI/Controls/Badge.xaml | 2 +- NeoUI/NeoUI/Controls/ButtonsStyle.xaml | 17 +- NeoUI/NeoUI/Controls/Card.xaml | 6 +- NeoUI/NeoUI/Controls/Cascader.xaml | 180 +- NeoUI/NeoUI/Controls/CheckBoxStyle.xaml | 14 +- NeoUI/NeoUI/Controls/ChooseBox.xaml | 70 +- NeoUI/NeoUI/Controls/ComboBoxStyle.xaml | 45 +- NeoUI/NeoUI/Controls/DataGridStyle.xaml | 2 +- .../Controls/Decorations/EmbossBorder.xaml | 1 + .../Controls/Decorations/SlotBorder.xaml | 4 +- NeoUI/NeoUI/Controls/Divider.xaml | 1 + NeoUI/NeoUI/Controls/GroupBoxStyle.xaml | 2 +- NeoUI/NeoUI/Controls/IconElement.xaml | 2 +- NeoUI/NeoUI/Controls/ListBoxStyle.xaml | 22 +- NeoUI/NeoUI/Controls/ListViewStyle.xaml | 2 +- NeoUI/NeoUI/Controls/NeuComboBox.xaml | 101 +- .../Notification/NotificationView.xaml | 71 +- NeoUI/NeoUI/Controls/PaginationControl.xaml | 14 +- NeoUI/NeoUI/Controls/PasswordBoxStyle.xaml | 143 +- NeoUI/NeoUI/Controls/Pill.xaml | 6 +- NeoUI/NeoUI/Controls/RadioButtonStyle.xaml | 8 +- NeoUI/NeoUI/Controls/Spin.xaml | 10 +- NeoUI/NeoUI/Controls/Tag.xaml | 4 +- NeoUI/NeoUI/Controls/TextBoxStyle.xaml | 28 +- NeoUI/NeoUI/Controls/Toast/ToastControl.xaml | 11 +- NeoUI/NeoUI/Controls/TreeViewStyle.xaml | 17 +- NeoUI/NeoUI/Controls/UploadArea.xaml | 4 +- .../Internal/AlphaToPercentConverter.cs | 4 +- .../Internal/ColorToHexConverter.cs | 4 +- .../Internal/ColorToOpaqueColorConverter.cs | 4 +- .../Internal/HueToBrushConverter.cs | 4 +- .../Internal/HueToColorConverter.cs | 4 +- NeoUI/NeoUI/NeoUI.csproj | 7 +- NeoUI/NeoUI/Themes/Dark.xaml | 22 +- NeoUI/NeoUI/Themes/Light.xaml | 18 +- NeoUI/NeoUI/Themes/Styles.xaml | 1 + NeoUI/NeoUITest/MainWindow.xaml | 203 ++- NeoUI/NeoUITest/MainWindow.xaml.cs | 10 +- ShrlAlgo.Addin.Test/ActionWindow.xaml | 9 +- .../ShrlAlgo.Addin.Test.csproj | 7 +- ShrlAlgoToolkit.Mvvm/Assists/BindingProxy.cs | 1 - .../ShrlAlgoToolkit.Mvvm.csproj | 3 - .../Assists/BuiltEnumDictionary.cs | 71 - ShrlAlgoToolkit.Revit/Assists/DMUAssist.cs | 40 - .../Assists/ParameterAssist.cs | 8 +- .../Extensions/SpatialExtensions.cs | 6 +- .../ShrlAlgoToolkit.Revit.projitems | 2 - .../UIRibbon/ModifyTabApp.cs | 12 +- ShrlAlgoToolkit.sln | 2 - 58 files changed, 933 insertions(+), 2241 deletions(-) delete mode 100644 AddinManager/AddinManager.csproj delete mode 100644 AddinManager/Services/AddinManagerService.cs create mode 100644 NeoUI/NeoUI/Controls/Accordion.xaml create mode 100644 NeoUI/NeoUI/Controls/Accordion.xaml.cs create mode 100644 NeoUI/NeoUI/Controls/AccordionItem.cs delete mode 100644 ShrlAlgoToolkit.Revit/Assists/BuiltEnumDictionary.cs delete mode 100644 ShrlAlgoToolkit.Revit/Assists/DMUAssist.cs diff --git a/AddinManager/AddinManager.csproj b/AddinManager/AddinManager.csproj deleted file mode 100644 index 82d0340..0000000 --- a/AddinManager/AddinManager.csproj +++ /dev/null @@ -1,76 +0,0 @@ - - - - net48 - true - x64 - x64 - 7.3 - Revit Addin Manager - Revit插件管理器,提供插件的安装、卸载、启用/禁用、热重载等功能 - ShrlAlgo - RevitAddinManager - Copyright © 2024 - 1.0.0.0 - 1.0.0.0 - true - false - false - REVIT_API_AVAILABLE - - - - - - ..\libs\2020\RevitAPI.dll - False - - - ..\libs\2020\RevitAPIUI.dll - False - - - - - - - C:\Program Files\Autodesk\Revit 2020\RevitAPI.dll - False - - - C:\Program Files\Autodesk\Revit 2020\RevitAPIUI.dll - False - - - - - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - - - - - \ No newline at end of file diff --git a/AddinManager/Services/AddinManagerService.cs b/AddinManager/Services/AddinManagerService.cs deleted file mode 100644 index 46ff63a..0000000 --- a/AddinManager/Services/AddinManagerService.cs +++ /dev/null @@ -1,1501 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Xml.Linq; - -using AddinManager.Models; - -using Newtonsoft.Json; - -namespace AddinManager.Services -{ - /// - /// 插件管理服务 - /// - public class AddinManagerService - { - private readonly string _revitVersion; - private readonly List _addinFolderPaths; - private readonly string _configPath; - private readonly Dictionary _loadedAssemblies = new Dictionary(); - - public AddinManagerService(string revitVersion = null) - { - _revitVersion = revitVersion ?? DetectCurrentRevitVersion(); - _addinFolderPaths = GetAllAddinDirectories(_revitVersion); - - // 配置文件放在用户目录下 - var userAddinPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - "Autodesk", "Revit", "Addins", _revitVersion); - _configPath = Path.Combine(userAddinPath, "AddinManagerConfig.json"); - - EnsureDirectoriesExist(); - } - - /// - /// 动态检测当前运行的Revit版本 - /// - private string DetectCurrentRevitVersion() - { - try - { - // 方法1:从当前运行的Revit进程检测 - var revitProcesses = Process.GetProcessesByName("Revit"); - if (revitProcesses.Length > 0) - { - var process = revitProcesses[0]; - var version = ExtractVersionFromProcess(process); - if (!string.IsNullOrEmpty(version)) - { - return version; - } - } - - // 方法2:从Revit API获取版本(如果在Revit环境中运行) - try - { - var app = AddinManagerApp.UiApplication.Application; - return app.VersionNumber; - } - catch - { - // 忽略Revit API获取失败 - } - // 方法3:从注册表获取最新安装的版本 - var installedVersions = GetInstalledRevitVersions(); - if (installedVersions.Count > 0) - { - return installedVersions.OrderByDescending(v => v).First(); - } - } - catch - { - // 忽略检测失败 - } - - // 默认返回2024版本 - return "2024"; - } - - /// - /// 从进程信息中提取Revit版本 - /// - private string ExtractVersionFromProcess(Process process) - { - try - { - var fileName = process.MainModule?.FileName; - if (!string.IsNullOrEmpty(fileName)) - { - var directory = Path.GetDirectoryName(fileName); - if (directory != null) - { - // 从路径中提取版本号 - for (int year = 2018; year <= 2030; year++) - { - if (directory.Contains(year.ToString())) - { - return year.ToString(); - } - } - } - - // 从文件版本信息中获取 - var versionInfo = FileVersionInfo.GetVersionInfo(fileName); - if (versionInfo.ProductVersion != null) - { - var match = System.Text.RegularExpressions.Regex.Match(versionInfo.ProductVersion, @"(\d{4})"); - if (match.Success) - { - return match.Groups[1].Value; - } - } - } - } - catch - { - // 忽略错误 - } - return null; - } - - /// - /// 获取系统中安装的所有Revit版本 - /// - private List GetInstalledRevitVersions() - { - var versions = new HashSet(); - - try - { - // 从注册表获取 - using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Autodesk\Revit")) - { - if (key != null) - { - foreach (var subKeyName in key.GetSubKeyNames()) - { - if (int.TryParse(subKeyName, out int year) && year >= 2018 && year <= 2030) - { - versions.Add(subKeyName); - } - } - } - } - - // 从WOW6432Node获取 - using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Autodesk\Revit")) - { - if (key != null) - { - foreach (var subKeyName in key.GetSubKeyNames()) - { - if (int.TryParse(subKeyName, out int year) && year >= 2018 && year <= 2030) - { - versions.Add(subKeyName); - } - } - } - } - - // 从文件系统检查 - var programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); - var programFilesX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86); - - foreach (var baseDir in new[] { programFiles, programFilesX86 }) - { - if (string.IsNullOrEmpty(baseDir)) continue; - - var autodeskDir = Path.Combine(baseDir, "Autodesk"); - if (Directory.Exists(autodeskDir)) - { - foreach (var dir in Directory.GetDirectories(autodeskDir, "Revit *")) - { - var dirName = Path.GetFileName(dir); - var match = System.Text.RegularExpressions.Regex.Match(dirName, @"Revit (\d{4})"); - if (match.Success) - { - versions.Add(match.Groups[1].Value); - } - } - } - } - } - catch - { - // 忽略错误 - } - - return versions.ToList(); - } - - /// - /// 获取所有可能的插件目录 - /// - private List GetAllAddinDirectories(string revitVersion) - { - var directories = new List(); - - // 1. 用户级插件目录 (当前用户) - .addin文件 - var userAddinPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - "Autodesk", "Revit", "Addins", revitVersion); - directories.Add(userAddinPath); - - // 2. 用户级ApplicationPlugins目录 - .bundle文件夹 - var userAppPluginsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - "Autodesk", "ApplicationPlugins"); - directories.Add(userAppPluginsPath); - - // 3. 全局插件目录 (所有用户) - .addin文件 - var globalAddinPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), - "Autodesk", "Revit", "Addins", revitVersion); - directories.Add(globalAddinPath); - - // 4. 全局ApplicationPlugins目录 - .bundle文件夹 - var globalAppPluginsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), - "Autodesk", "ApplicationPlugins"); - directories.Add(globalAppPluginsPath); - - // 5. 程序文件目录下的通用插件目录 - var programFilesAddinPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), - "Autodesk", $"Revit {revitVersion}", "AddIns"); - if (Directory.Exists(programFilesAddinPath)) - { - directories.Add(programFilesAddinPath); - } - - // 6. 程序文件(x86)目录下的插件目录 - var programFilesX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86); - if (!string.IsNullOrEmpty(programFilesX86)) - { - var programFilesX86AddinPath = Path.Combine(programFilesX86, "Autodesk", $"Revit {revitVersion}", "AddIns"); - if (Directory.Exists(programFilesX86AddinPath)) - { - directories.Add(programFilesX86AddinPath); - } - } - - // 去重并返回存在的目录 - return directories.Distinct().Where(Directory.Exists).ToList(); - } - - /// - /// 获取Revit的安装路径 - /// - private List GetRevitInstallPaths(string revitVersion) - { - var installPaths = new List(); - - try - { - // 从注册表查找Revit安装路径 - using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey($@"SOFTWARE\Autodesk\Revit\{revitVersion}")) - { - if (key != null) - { - var installPath = key.GetValue("InstallationPath") as string; - if (!string.IsNullOrEmpty(installPath) && Directory.Exists(installPath)) - { - installPaths.Add(installPath); - } - } - } - - // 从注册表查找其他可能的路径 (WOW6432Node for 32-bit apps on 64-bit Windows) - using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey($@"SOFTWARE\WOW6432Node\Autodesk\Revit\{revitVersion}")) - { - if (key != null) - { - var installPath = key.GetValue("InstallationPath") as string; - if (!string.IsNullOrEmpty(installPath) && Directory.Exists(installPath)) - { - installPaths.Add(installPath); - } - } - } - } - catch - { - // 忽略注册表读取错误 - } - - // 如果注册表查找失败,尝试常见的安装路径 - var commonPaths = new[] - { - Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Autodesk", $"Revit {revitVersion}"), - Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Autodesk", $"Revit {revitVersion}"), - Path.Combine("C:", "Program Files", "Autodesk", $"Revit {revitVersion}"), - Path.Combine("C:", "Program Files (x86)", "Autodesk", $"Revit {revitVersion}") - }; - - foreach (var path in commonPaths) - { - if (Directory.Exists(path)) - { - installPaths.Add(path); - } - } - - return installPaths.Distinct().ToList(); - } - - /// - /// 获取所有已安装的插件(包括已禁用的和Bundle格式的) - /// - public List GetInstalledAddins() - { - var addins = new List(); - - // 扫描所有插件目录 - foreach (var addinFolderPath in _addinFolderPaths) - { - if (!Directory.Exists(addinFolderPath)) - continue; - - try - { - // 检查是否是ApplicationPlugins目录(Bundle格式) - if (addinFolderPath.Contains("ApplicationPlugins")) - { - // 扫描Bundle格式插件 - var bundleAddins = ScanBundlePlugins(addinFolderPath); - addins.AddRange(bundleAddins); - } - else - { - // 扫描传统.addin文件格式 - var traditionalAddins = ScanTraditionalAddins(addinFolderPath); - addins.AddRange(traditionalAddins); - } - } - catch (Exception ex) - { - // 记录目录访问错误 - var errorAddin = new AddinInfo - { - Name = $"目录访问错误: {Path.GetFileName(addinFolderPath)}", - AddinFilePath = addinFolderPath, - SourceDirectory = addinFolderPath, - HasErrors = true, - ErrorMessages = new List { $"无法访问目录: {ex.Message}" }, - Status = "访问错误", - IsEnabled = false - }; - addins.Add(errorAddin); - } - } - - return addins; - } - - /// - /// 扫描传统.addin文件格式的插件 - /// - private List ScanTraditionalAddins(string addinFolderPath) - { - var addins = new List(); - - // 扫描所有.addin文件(包括.disabled文件) - var addinFiles = Directory.GetFiles(addinFolderPath, "*.addin", SearchOption.AllDirectories) - .Concat(Directory.GetFiles(addinFolderPath, "*.addin.disabled", SearchOption.AllDirectories)) - .ToArray(); - - foreach (var addinFile in addinFiles) - { - try - { - var addinInfos = ParseAddinFile(addinFile); - foreach (var addinInfo in addinInfos) - { - // 标记插件来源目录 - addinInfo.SourceDirectory = addinFolderPath; - addins.Add(addinInfo); - } - } - catch (Exception ex) - { - // 记录解析错误 - var errorAddin = new AddinInfo - { - Name = Path.GetFileNameWithoutExtension(addinFile), - AddinFilePath = addinFile, - SourceDirectory = addinFolderPath, - HasErrors = true, - ErrorMessages = new List { ex.Message }, - Status = "解析错误", - IsEnabled = false - }; - addins.Add(errorAddin); - } - } - - return addins; - } - - /// - /// 扫描Bundle格式的插件(.bundle文件夹) - /// - private List ScanBundlePlugins(string appPluginsPath) - { - var addins = new List(); - - // 查找所有.bundle文件夹 - var bundleFolders = Directory.GetDirectories(appPluginsPath, "*.bundle", SearchOption.TopDirectoryOnly); - - foreach (var bundleFolder in bundleFolders) - { - try - { - // 查找PackageContents.xml文件 - var packageContentsPath = Path.Combine(bundleFolder, "PackageContents.xml"); - if (File.Exists(packageContentsPath)) - { - var bundleAddins = ParseBundlePackage(packageContentsPath, bundleFolder); - addins.AddRange(bundleAddins); - } - else - { - // 如果没有PackageContents.xml,记录为错误 - var errorAddin = new AddinInfo - { - Name = Path.GetFileNameWithoutExtension(bundleFolder), - AddinFilePath = bundleFolder, - SourceDirectory = appPluginsPath, - HasErrors = true, - ErrorMessages = new List { "Bundle文件夹中缺少PackageContents.xml文件" }, - Status = "Bundle格式错误", - IsEnabled = false - }; - addins.Add(errorAddin); - } - } - catch (Exception ex) - { - // 记录Bundle解析错误 - var errorAddin = new AddinInfo - { - Name = Path.GetFileNameWithoutExtension(bundleFolder), - AddinFilePath = bundleFolder, - SourceDirectory = appPluginsPath, - HasErrors = true, - ErrorMessages = new List { $"Bundle解析错误: {ex.Message}" }, - Status = "Bundle解析错误", - IsEnabled = false - }; - addins.Add(errorAddin); - } - } - - return addins; - } - - /// - /// 解析Bundle格式的PackageContents.xml文件 - /// - private List ParseBundlePackage(string packageContentsPath, string bundleFolder) - { - var addins = new List(); - var doc = XDocument.Load(packageContentsPath); - - // 获取Bundle的基本信息 - var packageElement = doc.Element("ApplicationPackage"); - if (packageElement == null) return addins; - - var bundleName = packageElement.Attribute("Name")?.Value ?? Path.GetFileNameWithoutExtension(bundleFolder); - var bundleVersion = packageElement.Attribute("Version")?.Value ?? "Unknown"; - var bundleDescription = packageElement.Attribute("Description")?.Value ?? ""; - var bundleAuthor = packageElement.Attribute("Author")?.Value ?? "Unknown"; - - // 查找支持的Revit版本 - var supportedVersions = new List(); - var componentsElement = packageElement.Element("Components"); - if (componentsElement != null) - { - foreach (var runtimeRequirements in componentsElement.Descendants("RuntimeRequirements")) - { - var platform = runtimeRequirements.Attribute("Platform")?.Value; - var version = runtimeRequirements.Attribute("Version")?.Value; - - if (platform == "Revit" && !string.IsNullOrEmpty(version)) - { - supportedVersions.Add(version); - } - } - } - - // 查找所有的AddIn元素 - foreach (var componentElement in componentsElement?.Elements("ComponentEntry") ?? Enumerable.Empty()) - { - var moduleType = componentElement.Attribute("ModuleType")?.Value; - if (moduleType != "Managed") continue; // 只处理托管代码插件 - - var appName = componentElement.Attribute("AppName")?.Value ?? bundleName; - var appDescription = componentElement.Attribute("AppDescription")?.Value ?? bundleDescription; - - // 检查是否被禁用(通过重命名bundle文件夹) - bool isDisabled = bundleFolder.EndsWith(".bundle.disabled") || bundleFolder.EndsWith(".disabled"); - - var addin = new AddinInfo - { - Name = appName, - Description = appDescription, - Version = bundleVersion, - Developer = bundleAuthor, - AddinFilePath = packageContentsPath, - SourceDirectory = Path.GetDirectoryName(bundleFolder), - Type = AddinType.Application, // Bundle通常是Application类型 - CurrentRevitVersion = _revitVersion, - LastModified = File.GetLastWriteTime(packageContentsPath), - IsEnabled = !isDisabled, - Status = isDisabled ? "已禁用" : "已启用" - }; - - // 添加支持的版本 - foreach (var version in supportedVersions) - { - addin.SupportedRevitVersions.Add(version); - } - - // 查找程序集路径 - var appModule = componentElement.Element("AppModule"); - if (appModule != null) - { - var relativePath = appModule.Value; - if (!string.IsNullOrEmpty(relativePath)) - { - var assemblyPath = Path.Combine(bundleFolder, "Contents", relativePath); - addin.AssemblyPath = assemblyPath; - - // 尝试获取程序集版本信息 - if (File.Exists(assemblyPath)) - { - try - { - var assembly = Assembly.LoadFrom(assemblyPath); - var assemblyVersion = assembly.GetName().Version?.ToString(); - if (!string.IsNullOrEmpty(assemblyVersion)) - { - addin.Version = assemblyVersion; - } - - // 查找主类 - var types = assembly.GetTypes(); - var appType = types.FirstOrDefault(t => t.GetInterfaces() - .Any(i => i.Name.Contains("IExternalApplication"))); - if (appType != null) - { - addin.ClassName = appType.FullName; - } - } - catch - { - // 忽略程序集加载错误 - } - } - } - } - - addins.Add(addin); - } - - return addins; - } - - /// - /// 启用插件 - 支持传统.addin文件和Bundle格式 - /// - public bool EnableAddin(AddinInfo addin) - { - try - { - // 检查是否是Bundle格式插件 - if (IsBundlePlugin(addin)) - { - return EnableBundlePlugin(addin); - } - else - { - return EnableTraditionalPlugin(addin); - } - } - catch (Exception ex) - { - addin.ErrorMessages.Add($"启用失败: {ex.Message}"); - return false; - } - } - - /// - /// 禁用插件 - 支持传统.addin文件和Bundle格式 - /// - public bool DisableAddin(AddinInfo addin) - { - try - { - // 检查是否是Bundle格式插件 - if (IsBundlePlugin(addin)) - { - return DisableBundlePlugin(addin); - } - else - { - return DisableTraditionalPlugin(addin); - } - } - catch (Exception ex) - { - addin.ErrorMessages.Add($"禁用失败: {ex.Message}"); - return false; - } - } - - /// - /// 检查是否是Bundle格式插件 - /// - private bool IsBundlePlugin(AddinInfo addin) - { - return addin.AddinFilePath.Contains("ApplicationPlugins") && - addin.AddinFilePath.EndsWith("PackageContents.xml"); - } - - /// - /// 启用传统.addin文件格式插件 - /// - private bool EnableTraditionalPlugin(AddinInfo addin) - { - if (!File.Exists(addin.AddinFilePath)) - return false; - - // 如果文件以.disabled结尾,重命名回.addin - if (addin.AddinFilePath.EndsWith(".disabled")) - { - string enabledPath = addin.AddinFilePath.Replace(".addin.disabled", ".addin"); - File.Move(addin.AddinFilePath, enabledPath); - addin.AddinFilePath = enabledPath; - } - - addin.IsEnabled = true; - SaveAddinState(addin); - return true; - } - - /// - /// 禁用传统.addin文件格式插件 - /// - private bool DisableTraditionalPlugin(AddinInfo addin) - { - if (!File.Exists(addin.AddinFilePath)) - return false; - - // 如果文件以.addin结尾,重命名为.addin.disabled - if (addin.AddinFilePath.EndsWith(".addin")) - { - string disabledPath = addin.AddinFilePath + ".disabled"; - File.Move(addin.AddinFilePath, disabledPath); - addin.AddinFilePath = disabledPath; - } - - addin.IsEnabled = false; - SaveAddinState(addin); - return true; - } - - /// - /// 启用Bundle格式插件 - /// - private bool EnableBundlePlugin(AddinInfo addin) - { - var bundleFolder = Path.GetDirectoryName(addin.AddinFilePath); - if (!Directory.Exists(bundleFolder)) - return false; - - // 如果Bundle文件夹以.disabled结尾,重命名回.bundle - if (bundleFolder.EndsWith(".disabled")) - { - string enabledPath = bundleFolder.Replace(".bundle.disabled", ".bundle"); - Directory.Move(bundleFolder, enabledPath); - - // 更新插件信息中的路径 - addin.AddinFilePath = Path.Combine(enabledPath, "PackageContents.xml"); - addin.SourceDirectory = Path.GetDirectoryName(enabledPath); - } - else if (bundleFolder.EndsWith(".bundle.disabled")) - { - string enabledPath = bundleFolder.Replace(".bundle.disabled", ".bundle"); - Directory.Move(bundleFolder, enabledPath); - - // 更新插件信息中的路径 - addin.AddinFilePath = Path.Combine(enabledPath, "PackageContents.xml"); - addin.SourceDirectory = Path.GetDirectoryName(enabledPath); - } - - addin.IsEnabled = true; - SaveAddinState(addin); - return true; - } - - /// - /// 禁用Bundle格式插件 - /// - private bool DisableBundlePlugin(AddinInfo addin) - { - var bundleFolder = Path.GetDirectoryName(addin.AddinFilePath); - if (!Directory.Exists(bundleFolder)) - return false; - - // 如果Bundle文件夹以.bundle结尾,重命名为.bundle.disabled - if (bundleFolder.EndsWith(".bundle")) - { - string disabledPath = bundleFolder + ".disabled"; - Directory.Move(bundleFolder, disabledPath); - - // 更新插件信息中的路径 - addin.AddinFilePath = Path.Combine(disabledPath, "PackageContents.xml"); - addin.SourceDirectory = Path.GetDirectoryName(disabledPath); - } - - addin.IsEnabled = false; - SaveAddinState(addin); - return true; - } - - /// - /// 卸载插件 - /// - public bool UninstallAddin(AddinInfo addin) - { - try - { - // 删除.addin文件 - if (File.Exists(addin.AddinFilePath)) - { - File.Delete(addin.AddinFilePath); - } - - // 删除程序集文件(如果在插件目录下) - if (File.Exists(addin.AssemblyPath) && - _addinFolderPaths.Any(path => addin.AssemblyPath.StartsWith(path))) - { - File.Delete(addin.AssemblyPath); - } - - RemoveAddinState(addin); - return true; - } - catch (Exception ex) - { - addin.ErrorMessages.Add($"卸载失败: {ex.Message}"); - return false; - } - } - - /// - /// 热重载插件 - 增强版本 - /// - public bool HotReloadAddin(AddinInfo addin) - { - try - { - // 先禁用插件 - if (addin.IsEnabled) - { - DisableAddin(addin); - } - - // 卸载已加载的程序集 - if (_loadedAssemblies.ContainsKey(addin.AssemblyPath)) - { - _loadedAssemblies.Remove(addin.AssemblyPath); - } - - // 等待一段时间确保���件释放 - System.Threading.Thread.Sleep(500); - - // 重新启用插件 - EnableAddin(addin); - - addin.LastModified = File.GetLastWriteTime(addin.AssemblyPath); - return true; - } - catch (Exception ex) - { - addin.ErrorMessages.Add($"热重载失败: {ex.Message}"); - return false; - } - } - - /// - /// 安装插件 - /// - public bool InstallAddin(string addinFilePath, string targetDirectory = null) - { - try - { - if (targetDirectory == null) - { - // 默认安装到用户插件目录(第一个目录) - targetDirectory = _addinFolderPaths.FirstOrDefault() ?? - Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - "Autodesk", "Revit", "Addins", _revitVersion); - } - - var fileName = Path.GetFileName(addinFilePath); - var targetPath = Path.Combine(targetDirectory, fileName); - - File.Copy(addinFilePath, targetPath, true); - return true; - } - catch (Exception) - { - return false; - } - } - - /// - /// 检查插件兼容性 - /// - public bool CheckCompatibility(AddinInfo addin) - { - return addin.SupportedRevitVersions.Contains(_revitVersion) || - addin.SupportedRevitVersions.Count == 0; - } - - /// - /// 获取插件错误日志 - /// - public List GetAddinErrors(AddinInfo addin) - { - return addin.ErrorMessages; - } - - /// - /// 安装临时调试插件 - 直接加载到Revit中 - /// - public bool InstallTemporaryDebugAddin(CommandInfo commandInfo, string commandName) - { - try - { -#if REVIT_API_AVAILABLE - // 直接通过Revit API加载插件 - var uiApp = AddinManagerApp.UiApplication; - if (uiApp == null) - { - System.Diagnostics.Debug.WriteLine("Revit应用程序未初始化"); - return false; - } - - // 加载程序集 - var assembly = Assembly.LoadFrom(commandInfo.AssemblyPath); - var commandType = assembly.GetType(commandInfo.ClassName); - - if (commandType == null) - { - System.Diagnostics.Debug.WriteLine($"无法找到类型: {commandInfo.ClassName}"); - return false; - } - - // 创建外部命令数据 - var commandData = new Autodesk.Revit.UI.ExternalCommandData(); - - // 将命令添加到临时调试命令列表 - var tempCommandId = $"DebugCmd_{DateTime.Now:yyyyMMdd_HHmmss}_{Guid.NewGuid().ToString("N")[..8]}"; - - // 创建临时按钮(可选,用于UI访问) - try - { - var ribbonTab = uiApp.GetRibbonTabs().FirstOrDefault(t => t == "调试") ?? - uiApp.CreateRibbonTab("调试"); - - var panel = uiApp.GetRibbonPanels("调试").FirstOrDefault(p => p.Name == "临时命令") ?? - uiApp.CreateRibbonPanel("调试", "临时命令"); - - var buttonData = new Autodesk.Revit.UI.PushButtonData( - tempCommandId, - commandName, - commandInfo.AssemblyPath, - commandInfo.ClassName); - - var button = panel.AddItem(buttonData) as Autodesk.Revit.UI.PushButton; - if (button != null) - { - button.ToolTip = $"临时调试命令: {commandName}"; - button.LongDescription = $"从 {Path.GetFileName(commandInfo.AssemblyPath)} 加载的调试命令"; - } - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"创建临时按钮失败: {ex.Message}"); - // 即使按钮创建失败,命令仍然可以通过其他方式调用 - } - - // 记录已加载的临时命令 - if (!_loadedAssemblies.ContainsKey(commandInfo.AssemblyPath)) - { - _loadedAssemblies.Add(commandInfo.AssemblyPath, assembly); - } - - return true; -#else - // 在没有Revit API的环境中,仍然创建.addin文件作为fallback - return CreateTemporaryAddinFile(commandInfo, commandName); -#endif - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"直接加载插件失败: {ex.Message}"); - return false; - } - } - - /// - /// 创建临时.addin文件作为备用方案 - /// - private bool CreateTemporaryAddinFile(CommandInfo commandInfo, string commandName) - { - try - { - // 确保用户插件目录存在 - var userAddinPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - "Autodesk", "Revit", "Addins", _revitVersion); - - if (!Directory.Exists(userAddinPath)) - { - Directory.CreateDirectory(userAddinPath); - } - - // 生成临时插件的唯一标识 - var tempAddinId = $"DebugAddin_{DateTime.Now:yyyyMMdd_HHmmss}_{Guid.NewGuid().ToString("N")[..8]}"; - var tempAddinFileName = $"{tempAddinId}.addin"; - var tempAddinFilePath = Path.Combine(userAddinPath, tempAddinFileName); - - // 创建临时.addin文件内容 - var addinXml = CreateDebugAddinXml(commandInfo, commandName, tempAddinId); - - // 写入.addin文件 - File.WriteAllText(tempAddinFilePath, addinXml); - - return true; - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"创建临时addin文件失败: {ex.Message}"); - return false; - } - } - - /// - /// 直接执行命令(用于调试测试) - /// - public bool ExecuteCommand(CommandInfo commandInfo) - { - try - { -#if REVIT_API_AVAILABLE - var uiApp = AddinManagerApp.UiApplication; - if (uiApp == null) return false; - - // 加载程序集 - var assembly = Assembly.LoadFrom(commandInfo.AssemblyPath); - var commandType = assembly.GetType(commandInfo.ClassName); - - if (commandType == null) return false; - - // 创建命令实例 - var commandInstance = Activator.CreateInstance(commandType) as Autodesk.Revit.UI.IExternalCommand; - if (commandInstance == null) return false; - - // 准备命令数据 - var commandData = new Autodesk.Revit.UI.ExternalCommandData - { - Application = uiApp, - JournalData = new Autodesk.Revit.DB.NameValueMap() - }; - - var message = string.Empty; - var elementSet = new Autodesk.Revit.DB.ElementSet(); - - // 执行命令 - var result = commandInstance.Execute(commandData, ref message, elementSet); - - return result == Autodesk.Revit.UI.Result.Succeeded; -#else - return false; -#endif - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"执行命令失败: {ex.Message}"); - return false; - } - } - - /// - /// 卸载临时调试插件 - /// - public bool UnloadTemporaryDebugAddin(string assemblyPath) - { - try - { - // 从已加载程序集列表中移除 - if (_loadedAssemblies.ContainsKey(assemblyPath)) - { - _loadedAssemblies.Remove(assemblyPath); - } - - // 释放程序集引用 - ReleaseDllReferences(); - - return true; - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"卸载临时插件失败: {ex.Message}"); - return false; - } - } - - /// - /// 创建调试插件的XML内容 - /// - private string CreateDebugAddinXml(CommandInfo commandInfo, string commandName, string addinId) - { - var xml = $@" - - - {commandName} - {commandInfo.AssemblyPath} - {commandInfo.ClassName} - 临时调试插件 - {commandName} - AddinManager.Debug - Revit插件管理器调试功能 - {_revitVersion} - {commandInfo.TransactionMode} - -"; - - return xml; - } - - /// - /// 从DLL中获取命令信息 - /// - public List GetCommandsFromDll(string dllPath) - { - var commands = new List(); - - try - { - if (!File.Exists(dllPath)) - { - return commands; - } - - // 加载程序集 - var assembly = Assembly.LoadFrom(dllPath); - - // 查找实现IExternalCommand接口的类 - foreach (var type in assembly.GetTypes()) - { - if (type.IsClass && !type.IsAbstract) - { - // 检查是否实现了IExternalCommand接口 - var interfaces = type.GetInterfaces(); - bool implementsIExternalCommand = false; - - foreach (var interfaceType in interfaces) - { - if (interfaceType.Name == "IExternalCommand" || - interfaceType.FullName?.Contains("IExternalCommand") == true) - { - implementsIExternalCommand = true; - break; - } - } - - if (implementsIExternalCommand) - { - var commandInfo = new CommandInfo - { - ClassName = type.FullName, - AssemblyPath = dllPath, - Assembly = assembly, - Type = type, - TransactionMode = GetTransactionMode(type) - }; - - commands.Add(commandInfo); - } - } - } - } - catch (Exception ex) - { - // 返回错误信息 - var errorCommand = new CommandInfo - { - ClassName = "Error", - AssemblyPath = dllPath, - HasErrors = true, - ErrorMessage = ex.Message - }; - commands.Add(errorCommand); - } - - return commands; - } - - /// - /// 获取命令的事务模式 - /// - private string GetTransactionMode(Type type) - { - try - { - // 查找Transaction特性 - var transactionAttribute = type.GetCustomAttributes(false) - .FirstOrDefault(attr => attr.GetType().Name.Contains("Transaction")); - - if (transactionAttribute != null) - { - // 尝试获取事务模式值 - var modeProperty = transactionAttribute.GetType().GetProperty("Mode"); - if (modeProperty != null) - { - var modeValue = modeProperty.GetValue(transactionAttribute); - return modeValue?.ToString() ?? "Manual"; - } - } - - return "Manual"; // 默认事务模式 - } - catch - { - return "Manual"; - } - } - - /// - /// 附加到Revit进程进行调试 - /// - public bool AttachToRevitProcess() - { - try - { - var revitProcesses = Process.GetProcessesByName("Revit"); - if (revitProcesses.Length == 0) - { - return false; - } - - // 如果有多个Revit进程,选择第一个 - var revitProcess = revitProcesses[0]; - var processId = revitProcess.Id; - - // 尝试启动Visual Studio并附加到进程 - var vsInstances = GetVisualStudioInstances(); - if (vsInstances.Count > 0) - { - var vsPath = vsInstances.First(); - var startInfo = new ProcessStartInfo - { - FileName = vsPath, - Arguments = $"/debugexe", - UseShellExecute = true - }; - - Process.Start(startInfo); - return true; - } - - return false; - } - catch - { - return false; - } - } - - /// - /// 获取已安装的Visual Studio实例 - /// - private List GetVisualStudioInstances() - { - var instances = new List(); - - try - { - // 查找Visual Studio的常见安装路径 - var possiblePaths = new[] - { - @"Microsoft Visual Studio\2022\Enterprise\Common7\IDE\devenv.exe", - @"Microsoft Visual Studio\2022\Professional\Common7\IDE\devenv.exe", - @"Microsoft Visual Studio\2022\Community\Common7\IDE\devenv.exe", - @"Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe", - @"Microsoft Visual Studio\2019\Professional\Common7\IDE\devenv.exe", - @"Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe" - }; - - var programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); - var programFilesX86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86); - - foreach (var basePath in new[] { programFiles, programFilesX86 }) - { - if (string.IsNullOrEmpty(basePath)) continue; - - foreach (var relativePath in possiblePaths) - { - var fullPath = Path.Combine(basePath, relativePath); - if (File.Exists(fullPath)) - { - instances.Add(fullPath); - } - } - } - } - catch - { - // 忽略错误 - } - - return instances; - } - - /// - /// 清理临时调试插件 - /// - public void CleanupTemporaryDebugAddins() - { - try - { - var userAddinPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - "Autodesk", "Revit", "Addins", _revitVersion); - - if (!Directory.Exists(userAddinPath)) return; - - // 查找所有临时调试插件文件 - var tempFiles = Directory.GetFiles(userAddinPath, "DebugAddin_*.addin"); - - foreach (var tempFile in tempFiles) - { - try - { - // 检查文件是否超过1天,如果是则删除 - var fileInfo = new FileInfo(tempFile); - if (DateTime.Now - fileInfo.CreationTime > TimeSpan.FromDays(1)) - { - File.Delete(tempFile); - } - } - catch - { - // 忽略单个文件删除失败 - } - } - } - catch - { - // 忽略清理错误 - } - } - - /// - /// 释放程序集引用以便重新编译 - /// - public void ReleaseDllReferences() - { - try - { - _loadedAssemblies.Clear(); - - // 强制垃圾回收 - GC.Collect(); - GC.WaitForPendingFinalizers(); - GC.Collect(); - } - catch - { - // 忽略错误 - } - } - - private void EnsureDirectoriesExist() - { - foreach (var directory in _addinFolderPaths) - { - if (!Directory.Exists(directory)) - { - try - { - Directory.CreateDirectory(directory); - } - catch - { - // 忽略创建目录失败 - } - } - } - } - - private void SaveAddinState(AddinInfo addin) - { - try - { - var states = new Dictionary(); - - if (File.Exists(_configPath)) - { - var json = File.ReadAllText(_configPath); - states = JsonConvert.DeserializeObject>(json) ?? new Dictionary(); - } - - var key = $"{addin.ClassName}|{Path.GetFileNameWithoutExtension(addin.AddinFilePath)}"; - states[key] = addin.IsEnabled; - - var updatedJson = JsonConvert.SerializeObject(states, Formatting.Indented); - File.WriteAllText(_configPath, updatedJson); - } - catch - { - // 忽略保存错误 - } - } - - private void RemoveAddinState(AddinInfo addin) - { - try - { - if (!File.Exists(_configPath)) - return; - - var json = File.ReadAllText(_configPath); - var states = JsonConvert.DeserializeObject>(json); - - if (states != null) - { - var key = $"{addin.ClassName}|{Path.GetFileNameWithoutExtension(addin.AddinFilePath)}"; - if (states.ContainsKey(key)) - { - states.Remove(key); - var updatedJson = JsonConvert.SerializeObject(states, Formatting.Indented); - File.WriteAllText(_configPath, updatedJson); - } - } - } - catch - { - // 忽略错误 - } - } - - /// - /// 解析.addin文件 - /// - private List ParseAddinFile(string addinFilePath) - { - var addins = new List(); - var doc = XDocument.Load(addinFilePath); - - // 判断文件是否被禁用(通过文件扩展名) - bool isDisabled = addinFilePath.EndsWith(".disabled"); - - foreach (var addinElement in doc.Descendants("AddIn")) - { - var addin = new AddinInfo - { - AddinFilePath = addinFilePath, - CurrentRevitVersion = _revitVersion, - LastModified = File.GetLastWriteTime(addinFilePath), - IsEnabled = !isDisabled - }; - - // 解析类型 - var typeAttr = addinElement.Attribute("Type")?.Value; - switch (typeAttr) - { - case "Command": - addin.Type = AddinType.Command; - break; - case "Application": - addin.Type = AddinType.Application; - break; - case "ExternalDBApplication": - addin.Type = AddinType.ExternalDBApplication; - break; - default: - addin.Type = AddinType.Unknown; - break; - } - - addin.Name = addinElement.Element("Name")?.Value ?? "Unknown"; - addin.Description = addinElement.Element("Description")?.Value ?? ""; - addin.AssemblyPath = addinElement.Element("Assembly")?.Value ?? ""; - addin.ClassName = addinElement.Element("FullClassName")?.Value ?? ""; - addin.Developer = addinElement.Element("VendorId")?.Value ?? "Unknown"; - - // 解析版本兼容性 - var versionElements = addinElement.Elements("SupportedVersion"); - foreach (var versionElement in versionElements) - { - addin.SupportedRevitVersions.Add(versionElement.Value); - } - - // 如果程序集路径是相对路径,转换为绝对路径 - if (!Path.IsPathRooted(addin.AssemblyPath)) - { - addin.AssemblyPath = Path.Combine(Path.GetDirectoryName(addinFilePath), addin.AssemblyPath); - } - - // 尝试获取程序集版本信息 - if (File.Exists(addin.AssemblyPath)) - { - try - { - var assembly = Assembly.LoadFrom(addin.AssemblyPath); - addin.Version = assembly.GetName().Version?.ToString() ?? "Unknown"; - } - catch - { - addin.Version = "Unknown"; - } - } - - addins.Add(addin); - } - - return addins; - } - - /// - /// 获取正在运行的Revit进程 - /// - public List GetRevitProcesses() - { - var processes = new List(); - - try - { - var revitProcesses = Process.GetProcessesByName("Revit"); - - foreach (var process in revitProcesses) - { - try - { - var processInfo = new ProcessInfo - { - Id = process.Id, - ProcessName = process.ProcessName, - WindowTitle = process.MainWindowTitle, - StartTime = process.StartTime - }; - processes.Add(processInfo); - } - catch - { - // 忽略无法访问的进程 - } - } - } - catch - { - // 忽略获取进程失败 - } - - return processes; - } - - /// - /// 清理调试插件 - /// - public void CleanupDebugAddins() - { - try - { - // 清理临时调试文件 - CleanupTemporaryDebugAddins(); - - // 释放程序集引用 - ReleaseDllReferences(); - - System.Diagnostics.Debug.WriteLine("调试插件清理完成"); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine($"清理调试插件失败: {ex.Message}"); - } - } - } - - /// - /// 进程信息模型 - /// - public class ProcessInfo - { - public int Id { get; set; } - public string ProcessName { get; set; } - public string WindowTitle { get; set; } - public DateTime StartTime { get; set; } - } -} diff --git a/NeoUI/NeoUI/Animations/Animations.xaml b/NeoUI/NeoUI/Animations/Animations.xaml index 71ee311..2079a22 100644 --- a/NeoUI/NeoUI/Animations/Animations.xaml +++ b/NeoUI/NeoUI/Animations/Animations.xaml @@ -118,10 +118,20 @@ Storyboard.TargetProperty="Opacity" To="0.2" /> - + + + - \ No newline at end of file diff --git a/NeoUI/NeoUI/Assets/CommonGeometry.xaml b/NeoUI/NeoUI/Assets/CommonGeometry.xaml index 35052b2..f7ab91e 100644 --- a/NeoUI/NeoUI/Assets/CommonGeometry.xaml +++ b/NeoUI/NeoUI/Assets/CommonGeometry.xaml @@ -12,31 +12,31 @@ + - M567.7 514.9l254.8-254.6c15.4-15.4 15.4-40.3 0-55.6-15.4-15.4-40.3-15.4-55.6 0L512 459.2 257.1 204.6c-15.4-15.4-40.3-15.4-55.6 0-15.4 15.4-15.4 40.3 0 55.6l254.8 254.6-254.8 254.7c-15.4 15.4-15.4 40.3 0 55.6 7.7 7.7 17.8 11.5 27.8 11.5 10.1 0 20.1-3.8 27.8-11.5L512 570.5l254.9 254.7c7.7 7.7 17.7 11.5 27.8 11.5 10.1 0 20.1-3.8 27.8-11.5 15.4-15.4 15.4-40.3 0-55.6L567.7 514.9z M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3-22.2-52.4-53.9-99.4-94.3-139.9-40.4-40.4-87.5-72.2-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3 0.1 19.9-16 36-35.9 36z M512 384c19.9 0 36-16.1 36-36V36c0-19.9-16.1-36-36-36s-36 16.1-36 36v312c0 19.9 16.1 36 36 36zM512 1024c-69.1 0-136.2-13.5-199.3-40.2C251.7 958 197 921 150 874c-47-47-84-101.7-109.8-162.7C13.5 648.2 0 581.1 0 512c0-81.3 18.5-159.1 55-231.2 34.8-68.7 85.7-129.7 147.2-176.5 15.8-12 38.4-9 50.4 6.8s9 38.4-6.8 50.4c-52.8 40.2-96.6 92.7-126.5 151.7C87.9 375.3 72 442.1 72 512c0 59.4 11.6 117 34.6 171.3 22.2 52.4 53.9 99.5 94.3 139.9 40.4 40.4 87.5 72.2 139.9 94.3C395 940.4 452.6 952 512 952c59.4 0 117-11.6 171.3-34.6 52.4-22.2 99.5-53.9 139.9-94.3 40.4-40.4 72.2-87.5 94.3-139.9C940.4 629 952 571.4 952 512c0-69.9-15.9-136.7-47.3-198.6-29.9-59.1-73.7-111.5-126.5-151.7-15.8-12-18.9-34.6-6.8-50.4 12-15.8 34.6-18.9 50.4-6.8C883.2 151.3 934.1 212.3 969 281c36.5 72.1 55 149.8 55 231.2 0 69.1-13.5 136.2-40.2 199.3C958 772.3 921 827 874 874s-101.8 83.9-162.7 109.7c-63.1 26.8-130.2 40.3-199.3 40.3z M949.5 898.5L743.8 692.9C798.9 626.4 832 541.1 832 448c0-212.1-171.9-384-384-384S64 235.9 64 448s171.9 384 384 384c93.1 0 178.4-33.1 244.9-88.2l205.7 205.7c7 7 16.2 10.5 25.5 10.5s18.4-3.5 25.5-10.5c13.9-14.1 13.9-36.9-0.1-51z m-380.1-163C531 751.8 490.2 760 448 760s-83-8.2-121.4-24.5c-37.1-15.7-70.5-38.2-99.2-66.9-28.7-28.7-51.2-62.1-66.9-99.2C144.2 531 136 490.2 136 448s8.2-83 24.5-121.4c15.7-37.1 38.2-70.5 66.9-99.2 28.7-28.7 62.1-51.2 99.2-66.9C365 144.2 405.8 136 448 136s83 8.2 121.4 24.5c37.1 15.7 70.5 38.2 99.2 66.9 28.7 28.7 51.2 62.1 66.9 99.2C751.8 365 760 405.8 760 448s-8.2 83-24.5 121.4c-15.7 37.1-38.2 70.5-66.9 99.2-28.7 28.7-62 51.2-99.2 66.9z M858.5 763.6c-18.9-44.8-46.1-85-80.6-119.5-34.5-34.5-74.7-61.6-119.5-80.6-0.4-0.2-0.8-0.3-1.2-0.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-0.4 0.2-0.8 0.3-1.2 0.5-44.8 18.9-85 46-119.5 80.6-34.5 34.5-61.6 74.7-80.6 119.5C146.9 807.5 137 854 136 901.8c-0.1 4.5 3.5 8.2 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c0.1 4.4 3.6 7.8 8 7.8h60c4.5 0 8.1-3.7 8-8.2-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z - M721.3 305.6L393.8 634.1l-85.4-149.5c-9.9-17.3-31.8-23.3-49.1-13.4S236 503 245.9 520.3l108.8 190.5c6.6 11.6 18.8 18.2 31.3 18.2 6.1 0 12.2-1.5 17.8-4.7 3.2-1.9 6.1-4.1 8.5-6.7l0.4-0.4 359.5-360.6c14-14.1 14-36.9-0.1-50.9-14-14.2-36.7-14.2-50.8-0.1zM512 0C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229.2 512-512S794.8 0 512 0z m311.1 823.1c-40.4 40.4-87.5 72.2-139.9 94.3C629 940.4 571.4 952 512 952c-59.4 0-117-11.6-171.2-34.5-52.4-22.2-99.4-53.9-139.9-94.3-40.4-40.4-72.2-87.5-94.3-139.9C83.6 629 72 571.4 72 512c0-59.4 11.6-117 34.5-171.2 22.2-52.4 53.9-99.4 94.3-139.9 40.4-40.4 87.5-72.2 139.9-94.3C395 83.6 452.6 72 512 72c59.4 0 117 11.6 171.2 34.5 52.4 22.2 99.4 53.9 139.9 94.3 40.4 40.4 72.2 87.5 94.3 139.9C940.4 395 952 452.6 952 512c0 59.4-11.6 117-34.5 171.2-22.2 52.4-53.9 99.5-94.4 139.9z - M512 0C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229.2 512-512S794.8 0 512 0z m311.1 823.1c-40.4 40.4-87.5 72.2-139.9 94.3C629 940.4 571.4 952 512 952c-59.4 0-117-11.6-171.2-34.5-52.4-22.2-99.4-53.9-139.9-94.3-40.4-40.4-72.2-87.5-94.3-139.9C83.6 629 72 571.4 72 512c0-59.4 11.6-117 34.5-171.2 22.2-52.4 53.9-99.4 94.3-139.9 40.4-40.4 87.5-72.2 139.9-94.3C395 83.6 452.6 72 512 72c59.4 0 117 11.6 171.2 34.5 52.4 22.2 99.4 53.9 139.9 94.3 40.4 40.4 72.2 87.5 94.3 139.9C940.4 395 952 452.6 952 512c0 59.4-11.6 117-34.5 171.2-22.2 52.4-53.9 99.5-94.4 139.9zM630.2 705.6H545V355.5c0-19.9-16.1-36-36-36h-96c-19.9 0-36 16.1-36 36s16.1 36 36 36h60v314.1h-85.2c-19.9 0-36 16.1-36 36s16.1 36 36 36H630.2c19.9 0 36-16.1 36-36s-16.1-36-36-36zM473 220.5a36 36 0 1 0 72 0 36 36 0 1 0-72 0z - M512 72c59.4 0 117 11.6 171.2 34.5 52.4 22.2 99.4 53.9 139.9 94.3 40.4 40.4 72.2 87.5 94.3 139.9C940.4 395 952 452.6 952 512s-11.6 117-34.5 171.2c-22.2 52.4-53.9 99.4-94.3 139.9-40.4 40.4-87.5 72.2-139.9 94.3C629 940.4 571.4 952 512 952s-117-11.6-171.2-34.5c-52.4-22.2-99.4-53.9-139.9-94.3-40.4-40.4-72.2-87.5-94.3-139.9C83.6 629 72 571.4 72 512s11.6-117 34.5-171.2c22.2-52.4 53.9-99.4 94.3-139.9 40.4-40.4 87.5-72.2 139.9-94.3C395 83.6 452.6 72 512 72m0-72C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229.2 512-512S794.8 0 512 0z m0 640c-22.1 0-40-17.9-40-40V231c0-22.1 17.9-40 40-40s40 17.9 40 40v369c0 22.1-17.9 40-40 40z m-45 109a45 45 0 1 0 90 0 45 45 0 1 0-90 0z - M717.2 306.2c-14.1-14-36.9-14-50.9 0.1L512 461 357.7 306.3c-14-14.1-36.8-14.1-50.9-0.1-14.1 14-14.1 36.8-0.1 50.9L461.2 512 306.7 666.9c-14 14.1-14 36.9 0.1 50.9 7 7 16.2 10.5 25.4 10.5s18.5-3.5 25.5-10.6L512 563l154.3 154.8c7 7.1 16.3 10.6 25.5 10.6s18.4-3.5 25.4-10.5c14.1-14 14.1-36.8 0.1-50.9L562.8 512l154.4-154.9c14.1-14.1 14.1-36.9 0-50.9zM512 0C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229.2 512-512S794.8 0 512 0z m311.1 823.1c-40.4 40.4-87.5 72.2-139.9 94.3C629 940.4 571.4 952 512 952c-59.4 0-117-11.6-171.2-34.5-52.4-22.2-99.4-53.9-139.9-94.3-40.4-40.4-72.2-87.5-94.3-139.9C83.6 629 72 571.4 72 512c0-59.4 11.6-117 34.5-171.2 22.2-52.4 53.9-99.4 94.3-139.9 40.4-40.4 87.5-72.2 139.9-94.3C395 83.6 452.6 72 512 72c59.4 0 117 11.6 171.2 34.5 52.4 22.2 99.4 53.9 139.9 94.3 40.4 40.4 72.2 87.5 94.3 139.9C940.4 395 952 452.6 952 512c0 59.4-11.6 117-34.5 171.2-22.2 52.4-53.9 99.5-94.4 139.9z - M963.4 511.7c-0.3-5.6-8.9-33.3-20.9-62.1-12.3-29.7-33.1-72.7-61.9-108.6-37.7-47.2-84.2-84.9-138.2-111.9-66.3-33.3-143.9-50.1-230.5-50.1-86.5 0-164.1 16.9-230.4 50.2C227.9 256 181.4 293.6 143.3 341c-28.8 36-49.5 79-61.8 108.7-12 28.8-20.5 56.5-20.8 62.1v0.4c0.3 5.6 8.9 33.3 20.9 62.2 12.4 29.7 33.1 72.7 61.8 108.5 37.7 47.2 84.2 84.9 138.2 111.9 66.7 33.4 144.2 50.3 230.4 50.3 86.3 0 163.8-16.9 230.4-50.3 53.8-26.9 100.3-64.6 138.2-111.8 28.8-35.9 49.6-78.9 61.9-108.6 12-28.8 20.6-56.5 20.9-62.1v-0.2-0.4z m-74.2 0.2c-5.7 17.4-27.8 80.2-64.4 125.8l-0.5 0.5c-31.1 39-69.6 70.1-114.3 92.6-56.5 28.3-123.3 42.7-198.4 42.7-75.2 0-141.9-14.4-198.4-42.7-44.6-22.3-83-53.5-114.3-92.7-36.8-45.8-59-108.8-64.7-126.3 5.7-17.4 27.9-80.3 64.7-126.3 31.4-39.2 69.9-70.3 114.4-92.6 56.6-28.3 123.4-42.6 198.6-42.6 75.5 0 142.2 14.3 198.3 42.6 44.6 22.3 83 53.5 114.3 92.7 36.8 46 59 108.9 64.7 126.3zM511.9 337.8c-95.6 0-173.3 77.8-173.3 173.3s77.8 173.3 173.3 173.3 173.3-77.8 173.3-173.3-77.7-173.3-173.3-173.3z m102 173.3c0 27.2-10.6 52.8-29.9 72.1-19.3 19.3-44.9 29.9-72.1 29.9-27.2 0-52.8-10.6-72.1-29.9-19.3-19.3-29.9-44.9-29.9-72.1 0-27.2 10.6-52.8 29.9-72.1 19.3-19.3 44.9-29.9 72.1-29.9 27.2 0 52.8 10.6 72.1 29.9 19.3 19.3 29.9 44.9 29.9 72.1z M895.7 300.1c0 9.6-3.2 19.3-9.6 27.4L545.2 751.3c-8.3 10.3-20.8 16.3-34.1 16.3-13.2 0-25.8-6-34-16.3L138 329.3c-15.1-18.8-12.1-46.3 6.7-61.4 18.8-15.1 46.3-12.1 61.4 6.7l305.1 379.6L818 272.7c15.1-18.8 42.6-21.8 61.4-6.7 10.7 8.7 16.3 21.3 16.3 34.1z M895.7 659.9c0-9.6-3.2-19.3-9.6-27.4L545.2 208.7c-8.3-10.3-20.8-16.3-34.1-16.3-13.2 0-25.8 6-34 16.3L138 630.7c-15.1 18.8-12.1 46.3 6.7 61.4 18.8 15.1 46.3 12.1 61.4-6.7l305.1-379.6L818 687.3c15.1 18.8 42.6 21.8 61.4 6.7 10.7-8.7 16.3-21.3 16.3-34.1z M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240z m460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53c12.1-8.7 20-22.9 20-39 0-26.5-21.5-48-48-48s-48 21.5-48 48c0 16.1 7.9 30.3 20 39z + + + M721.3 305.6L393.8 634.1l-85.4-149.5c-9.9-17.3-31.8-23.3-49.1-13.4S236 503 245.9 520.3l108.8 190.5c6.6 11.6 18.8 18.2 31.3 18.2 6.1 0 12.2-1.5 17.8-4.7 3.2-1.9 6.1-4.1 8.5-6.7l0.4-0.4 359.5-360.6c14-14.1 14-36.9-0.1-50.9-14-14.2-36.7-14.2-50.8-0.1zM512 0C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229.2 512-512S794.8 0 512 0z m311.1 823.1c-40.4 40.4-87.5 72.2-139.9 94.3C629 940.4 571.4 952 512 952c-59.4 0-117-11.6-171.2-34.5-52.4-22.2-99.4-53.9-139.9-94.3-40.4-40.4-72.2-87.5-94.3-139.9C83.6 629 72 571.4 72 512c0-59.4 11.6-117 34.5-171.2 22.2-52.4 53.9-99.4 94.3-139.9 40.4-40.4 87.5-72.2 139.9-94.3C395 83.6 452.6 72 512 72c59.4 0 117 11.6 171.2 34.5 52.4 22.2 99.4 53.9 139.9 94.3 40.4 40.4 72.2 87.5 94.3 139.9C940.4 395 952 452.6 952 512c0 59.4-11.6 117-34.5 171.2-22.2 52.4-53.9 99.5-94.4 139.9z + + M512 0C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229.2 512-512S794.8 0 512 0z m311.1 823.1c-40.4 40.4-87.5 72.2-139.9 94.3C629 940.4 571.4 952 512 952c-59.4 0-117-11.6-171.2-34.5-52.4-22.2-99.4-53.9-139.9-94.3-40.4-40.4-72.2-87.5-94.3-139.9C83.6 629 72 571.4 72 512c0-59.4 11.6-117 34.5-171.2 22.2-52.4 53.9-99.4 94.3-139.9 40.4-40.4 87.5-72.2 139.9-94.3C395 83.6 452.6 72 512 72c59.4 0 117 11.6 171.2 34.5 52.4 22.2 99.4 53.9 139.9 94.3 40.4 40.4 72.2 87.5 94.3 139.9C940.4 395 952 452.6 952 512c0 59.4-11.6 117-34.5 171.2-22.2 52.4-53.9 99.5-94.4 139.9zM630.2 705.6H545V355.5c0-19.9-16.1-36-36-36h-96c-19.9 0-36 16.1-36 36s16.1 36 36 36h60v314.1h-85.2c-19.9 0-36 16.1-36 36s16.1 36 36 36H630.2c19.9 0 36-16.1 36-36s-16.1-36-36-36zM473 220.5a36 36 0 1 0 72 0 36 36 0 1 0-72 0z + + M512 72c59.4 0 117 11.6 171.2 34.5 52.4 22.2 99.4 53.9 139.9 94.3 40.4 40.4 72.2 87.5 94.3 139.9C940.4 395 952 452.6 952 512s-11.6 117-34.5 171.2c-22.2 52.4-53.9 99.4-94.3 139.9-40.4 40.4-87.5 72.2-139.9 94.3C629 940.4 571.4 952 512 952s-117-11.6-171.2-34.5c-52.4-22.2-99.4-53.9-139.9-94.3-40.4-40.4-72.2-87.5-94.3-139.9C83.6 629 72 571.4 72 512s11.6-117 34.5-171.2c22.2-52.4 53.9-99.4 94.3-139.9 40.4-40.4 87.5-72.2 139.9-94.3C395 83.6 452.6 72 512 72m0-72C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229.2 512-512S794.8 0 512 0z m0 640c-22.1 0-40-17.9-40-40V231c0-22.1 17.9-40 40-40s40 17.9 40 40v369c0 22.1-17.9 40-40 40z m-45 109a45 45 0 1 0 90 0 45 45 0 1 0-90 0z + + M717.2 306.2c-14.1-14-36.9-14-50.9 0.1L512 461 357.7 306.3c-14-14.1-36.8-14.1-50.9-0.1-14.1 14-14.1 36.8-0.1 50.9L461.2 512 306.7 666.9c-14 14.1-14 36.9 0.1 50.9 7 7 16.2 10.5 25.4 10.5s18.5-3.5 25.5-10.6L512 563l154.3 154.8c7 7.1 16.3 10.6 25.5 10.6s18.4-3.5 25.4-10.5c14.1-14 14.1-36.8 0.1-50.9L562.8 512l154.4-154.9c14.1-14.1 14.1-36.9 0-50.9zM512 0C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229.2 512-512S794.8 0 512 0z m311.1 823.1c-40.4 40.4-87.5 72.2-139.9 94.3C629 940.4 571.4 952 512 952c-59.4 0-117-11.6-171.2-34.5-52.4-22.2-99.4-53.9-139.9-94.3-40.4-40.4-72.2-87.5-94.3-139.9C83.6 629 72 571.4 72 512c0-59.4 11.6-117 34.5-171.2 22.2-52.4 53.9-99.4 94.3-139.9 40.4-40.4 87.5-72.2 139.9-94.3C395 83.6 452.6 72 512 72c59.4 0 117 11.6 171.2 34.5 52.4 22.2 99.4 53.9 139.9 94.3 40.4 40.4 72.2 87.5 94.3 139.9C940.4 395 952 452.6 952 512c0 59.4-11.6 117-34.5 171.2-22.2 52.4-53.9 99.5-94.4 139.9z - - + \ No newline at end of file diff --git a/NeoUI/NeoUI/Controls/Accordion.xaml b/NeoUI/NeoUI/Controls/Accordion.xaml new file mode 100644 index 0000000..e3d11e4 --- /dev/null +++ b/NeoUI/NeoUI/Controls/Accordion.xaml @@ -0,0 +1,161 @@ + + + + + + + \ No newline at end of file diff --git a/NeoUI/NeoUI/Controls/Accordion.xaml.cs b/NeoUI/NeoUI/Controls/Accordion.xaml.cs new file mode 100644 index 0000000..1e34d7c --- /dev/null +++ b/NeoUI/NeoUI/Controls/Accordion.xaml.cs @@ -0,0 +1,99 @@ +using System.Windows; +using System.Windows.Controls; + +namespace NeoUI.Controls +{ + public class Accordion : ItemsControl + { + static Accordion() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(Accordion), new FrameworkPropertyMetadata(typeof(Accordion))); + } + + protected override bool IsItemItsOwnContainerOverride(object item) + { + return item is AccordionItem; + } + + protected override DependencyObject GetContainerForItemOverride() + { + return new AccordionItem(); + } + + protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + base.OnItemsChanged(e); + + if (e.NewItems != null) + { + // 注意:这里需要确保 e.NewItems 中的项是 AccordionItem 类型 + // 当通过 ItemsSource 绑定时,它们最初是数据项,在 GetContainerForItemOverride 之后才被包装 + // 因此,事件处理最好在容器生成后进行。 + // 为了简单起见,我们在此处添加事件,但这依赖于 ItemsSource 中的项已经是 AccordionItem。 + // 一个更健壮的方法是重写 PrepareContainerForItemOverride。 + foreach (AccordionItem item in e.NewItems) + { + item.PreviewMouseLeftButtonDown += AccordionItem_PreviewMouseLeftButtonDown; + } + } + if (e.OldItems != null) + { + foreach (AccordionItem item in e.OldItems) + { + item.PreviewMouseLeftButtonDown -= AccordionItem_PreviewMouseLeftButtonDown; + } + } + } + + // 重写此方法是处理数据绑定时添加事件的更可靠方式 + protected override void PrepareContainerForItemOverride(DependencyObject element, object item) + { + base.PrepareContainerForItemOverride(element, item); + if (element is AccordionItem accordionItem) + { + accordionItem.PreviewMouseLeftButtonDown -= AccordionItem_PreviewMouseLeftButtonDown; // 防止重复添加 + accordionItem.PreviewMouseLeftButtonDown += AccordionItem_PreviewMouseLeftButtonDown; + } + } + + protected override void ClearContainerForItemOverride(DependencyObject element, object item) + { + if (element is AccordionItem accordionItem) + { + accordionItem.PreviewMouseLeftButtonDown -= AccordionItem_PreviewMouseLeftButtonDown; + } + base.ClearContainerForItemOverride(element, item); + } + + private void AccordionItem_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) + { + if (sender is AccordionItem clickedItem) + { + // 如果点击一个已展开的项的头部,则折叠它 + if (clickedItem.IsExpanded) + { + // 检查点击的原始源是否是 ToggleButton 或其子元素 + if (e.OriginalSource is FrameworkElement fe && fe.TemplatedParent is System.Windows.Controls.Primitives.ToggleButton) + { + clickedItem.IsExpanded = false; + e.Handled = true; // 阻止事件继续传播 + } + } + else // 否则展开点击的项,并折叠其他所有项 + { + // 遍历 ItemsControl 中的所有容器 + for (int i = 0; i < Items.Count; i++) + { + var container = ItemContainerGenerator.ContainerFromIndex(i) as AccordionItem; + if (container != null && container != clickedItem) + { + container.IsExpanded = false; + } + } + clickedItem.IsExpanded = true; + e.Handled = true; + } + } + } + } +} \ No newline at end of file diff --git a/NeoUI/NeoUI/Controls/AccordionItem.cs b/NeoUI/NeoUI/Controls/AccordionItem.cs new file mode 100644 index 0000000..a5976d1 --- /dev/null +++ b/NeoUI/NeoUI/Controls/AccordionItem.cs @@ -0,0 +1,22 @@ +using System.Windows; +using System.Windows.Controls; + +namespace NeoUI.Controls +{ + public class AccordionItem : HeaderedContentControl + { + static AccordionItem() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(AccordionItem), new FrameworkPropertyMetadata(typeof(AccordionItem))); + } + + public static readonly DependencyProperty IsExpandedProperty = + DependencyProperty.Register("IsExpanded", typeof(bool), typeof(AccordionItem), new PropertyMetadata(false)); + + public bool IsExpanded + { + get { return (bool)GetValue(IsExpandedProperty); } + set { SetValue(IsExpandedProperty, value); } + } + } +} \ No newline at end of file diff --git a/NeoUI/NeoUI/Controls/Alert.xaml b/NeoUI/NeoUI/Controls/Alert.xaml index 1f954e2..dbd3fae 100644 --- a/NeoUI/NeoUI/Controls/Alert.xaml +++ b/NeoUI/NeoUI/Controls/Alert.xaml @@ -1,16 +1,17 @@  + xmlns:converters="clr-namespace:NeoUI.Converters" + xmlns:decorations="clr-namespace:NeoUI.Controls.Decorations"> - + --> - + + + + + + + + @@ -214,19 +238,19 @@ - + - + - - + + - - + + @@ -234,15 +258,15 @@ - - + + - - - + + + @@ -293,6 +317,7 @@ + diff --git a/NeoUI/NeoUI/Controls/Pill.xaml b/NeoUI/NeoUI/Controls/Pill.xaml index f5d722b..bc64534 100644 --- a/NeoUI/NeoUI/Controls/Pill.xaml +++ b/NeoUI/NeoUI/Controls/Pill.xaml @@ -1,7 +1,7 @@  @@ -20,7 +20,7 @@ - - + diff --git a/NeoUI/NeoUI/Controls/RadioButtonStyle.xaml b/NeoUI/NeoUI/Controls/RadioButtonStyle.xaml index 5040f09..f3fb206 100644 --- a/NeoUI/NeoUI/Controls/RadioButtonStyle.xaml +++ b/NeoUI/NeoUI/Controls/RadioButtonStyle.xaml @@ -1,6 +1,6 @@  @@ -46,7 +46,10 @@ - + @@ -122,7 +125,7 @@ VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Visibility="Collapsed" x:Name="Placeholder" /> - + + + + + + + + + + + @@ -292,7 +308,7 @@ VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Visibility="Collapsed" x:Name="Placeholder" /> - + - + + + + - + - + - + - + diff --git a/NeoUI/NeoUI/Controls/TreeViewStyle.xaml b/NeoUI/NeoUI/Controls/TreeViewStyle.xaml index 9a6d351..692c3d2 100644 --- a/NeoUI/NeoUI/Controls/TreeViewStyle.xaml +++ b/NeoUI/NeoUI/Controls/TreeViewStyle.xaml @@ -152,18 +152,23 @@ - - - + - - - + + + + + + + + + + diff --git a/NeoUI/NeoUI/Controls/UploadArea.xaml b/NeoUI/NeoUI/Controls/UploadArea.xaml index 14975fa..a407214 100644 --- a/NeoUI/NeoUI/Controls/UploadArea.xaml +++ b/NeoUI/NeoUI/Controls/UploadArea.xaml @@ -1,6 +1,6 @@  @@ -135,7 +135,7 @@ - + diff --git a/NeoUI/NeoUI/Converters/Internal/AlphaToPercentConverter.cs b/NeoUI/NeoUI/Converters/Internal/AlphaToPercentConverter.cs index aeb49eb..1113c26 100644 --- a/NeoUI/NeoUI/Converters/Internal/AlphaToPercentConverter.cs +++ b/NeoUI/NeoUI/Converters/Internal/AlphaToPercentConverter.cs @@ -13,7 +13,7 @@ internal class AlphaToPercentConverter : IValueConverter { public static readonly AlphaToPercentConverter Instance = new(); /// - public object Convert(object? value, System.Type targetType, object? parameter, CultureInfo culture) + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is byte alpha) { @@ -25,7 +25,7 @@ internal class AlphaToPercentConverter : IValueConverter } /// - public object ConvertBack(object? value, System.Type targetType, object? parameter, CultureInfo culture) + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is string percentStr) { diff --git a/NeoUI/NeoUI/Converters/Internal/ColorToHexConverter.cs b/NeoUI/NeoUI/Converters/Internal/ColorToHexConverter.cs index efe1132..97c5801 100644 --- a/NeoUI/NeoUI/Converters/Internal/ColorToHexConverter.cs +++ b/NeoUI/NeoUI/Converters/Internal/ColorToHexConverter.cs @@ -11,10 +11,10 @@ namespace NeoUI.Converters.Internal; internal class ColorToHexConverter : IValueConverter { public static readonly ColorToHexConverter Instance = new(); - public object Convert(object? value, System.Type t, object? p, CultureInfo c) => + public object Convert(object? value, Type t, object? p, CultureInfo c) => value is Color color ? $"#{color.A:X2}{color.R:X2}{color.G:X2}{color.B:X2}".ToUpper() : "#FFFFFFFF"; - public object? ConvertBack(object? value, System.Type t, object? p, CultureInfo c) + public object? ConvertBack(object? value, Type t, object? p, CultureInfo c) { if (value is not string hexStr || string.IsNullOrWhiteSpace(hexStr)) { diff --git a/NeoUI/NeoUI/Converters/Internal/ColorToOpaqueColorConverter.cs b/NeoUI/NeoUI/Converters/Internal/ColorToOpaqueColorConverter.cs index ab54209..439d58c 100644 --- a/NeoUI/NeoUI/Converters/Internal/ColorToOpaqueColorConverter.cs +++ b/NeoUI/NeoUI/Converters/Internal/ColorToOpaqueColorConverter.cs @@ -13,7 +13,7 @@ internal class ColorToOpaqueColorConverter : IValueConverter public static readonly ColorToOpaqueColorConverter Instance = new(); /// public object Convert(object? value, - System.Type t, + Type t, object? p, CultureInfo cul) => value is Color c @@ -24,7 +24,7 @@ internal class ColorToOpaqueColorConverter : IValueConverter /// public object ConvertBack(object? v, - System.Type t, + Type t, object? p, CultureInfo c) => Binding.DoNothing; diff --git a/NeoUI/NeoUI/Converters/Internal/HueToBrushConverter.cs b/NeoUI/NeoUI/Converters/Internal/HueToBrushConverter.cs index 91f6b3c..4f760c7 100644 --- a/NeoUI/NeoUI/Converters/Internal/HueToBrushConverter.cs +++ b/NeoUI/NeoUI/Converters/Internal/HueToBrushConverter.cs @@ -22,7 +22,7 @@ internal class HueToBrushConverter : IValueConverter /// 文化信息,提供关于语言、国家/地区等的信息,以支持区域性特定的转换,本方法中未使用。 /// 如果输入值是有效的int类型色相值,则返回对应的颜色画刷;否则返回一个透明画刷。 public object Convert(object? value, - System.Type t, + Type t, object? p, CultureInfo c) => value is int hue @@ -42,7 +42,7 @@ internal class HueToBrushConverter : IValueConverter /// 由于方法未实现,实际上不返回任何有意义的数据,并且总是抛出异常。 /// 始终抛出此异常,因为ConvertBack方法在当前版本中没有具体实现。 public object ConvertBack(object? v, - System.Type t, + Type t, object? p, CultureInfo c) => Binding.DoNothing; diff --git a/NeoUI/NeoUI/Converters/Internal/HueToColorConverter.cs b/NeoUI/NeoUI/Converters/Internal/HueToColorConverter.cs index cbffbf3..118c60b 100644 --- a/NeoUI/NeoUI/Converters/Internal/HueToColorConverter.cs +++ b/NeoUI/NeoUI/Converters/Internal/HueToColorConverter.cs @@ -15,7 +15,7 @@ namespace NeoUI.Converters.Internal; internal class HueToColorConverter : IValueConverter { public object Convert(object? value, - System.Type t, + Type t, object? p, CultureInfo c) => value is int hue @@ -25,7 +25,7 @@ internal class HueToColorConverter : IValueConverter 255) : Colors.Transparent; - public object ConvertBack(object? value, System.Type t, object? p, CultureInfo c) + public object ConvertBack(object? value, Type t, object? p, CultureInfo c) { if (value is Color color) { diff --git a/NeoUI/NeoUI/NeoUI.csproj b/NeoUI/NeoUI/NeoUI.csproj index 64310d2..1231c9a 100644 --- a/NeoUI/NeoUI/NeoUI.csproj +++ b/NeoUI/NeoUI/NeoUI.csproj @@ -37,16 +37,11 @@ - - - - - - diff --git a/NeoUI/NeoUI/Themes/Dark.xaml b/NeoUI/NeoUI/Themes/Dark.xaml index f32ac94..6d7ff7d 100644 --- a/NeoUI/NeoUI/Themes/Dark.xaml +++ b/NeoUI/NeoUI/Themes/Dark.xaml @@ -119,7 +119,7 @@ #1B5E20 - + + + + + #e0e6ed - #657075 + #6d7a7d #767676 #1C1E22 - #757575 + #595b60 - + + \ No newline at end of file diff --git a/NeoUI/NeoUI/Themes/Light.xaml b/NeoUI/NeoUI/Themes/Light.xaml index b4f2c1f..96861a8 100644 --- a/NeoUI/NeoUI/Themes/Light.xaml +++ b/NeoUI/NeoUI/Themes/Light.xaml @@ -119,7 +119,7 @@ #186A3B - + - #FFFFFF + #EFF2F7 #50000000 - - + + + - + \ No newline at end of file diff --git a/NeoUI/NeoUI/Themes/Styles.xaml b/NeoUI/NeoUI/Themes/Styles.xaml index a5b3d7e..b7144e8 100644 --- a/NeoUI/NeoUI/Themes/Styles.xaml +++ b/NeoUI/NeoUI/Themes/Styles.xaml @@ -54,6 +54,7 @@ + diff --git a/NeoUI/NeoUITest/MainWindow.xaml b/NeoUI/NeoUITest/MainWindow.xaml index e8f9c55..aa83862 100644 --- a/NeoUI/NeoUITest/MainWindow.xaml +++ b/NeoUI/NeoUITest/MainWindow.xaml @@ -156,45 +156,38 @@ - - - - - - - - - - - - - + + + + + + - + @@ -287,15 +280,11 @@ - - - + - - @@ -996,7 +985,7 @@ - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - + - - + + - -