From ce4cc7bed077f589a6be6a0ba149ea1e3f9b6dd0 Mon Sep 17 00:00:00 2001 From: ShrlAlgo <903524121@qq.com> Date: Mon, 25 Aug 2025 17:30:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=87=E5=AD=97=E9=94=99?= =?UTF-8?q?=E8=AF=AF=EF=BC=8C=E5=92=8C=E9=83=A8=E5=88=86=E9=85=8D=E8=89=B2?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Appearance/ResourceDictionaryManager.cs | 132 ------- NeoUI/NeoUI/Appearance/ThemeManager.cs | 204 +++++----- NeoUI/NeoUI/Appearance/ThemesDictionary.cs | 44 +-- NeoUI/NeoUI/Controls/Alert.xaml | 4 +- NeoUI/NeoUI/Controls/Anchor.xaml | 2 +- NeoUI/NeoUI/Controls/Avatar.xaml | 2 +- NeoUI/NeoUI/Controls/Breadcrumb.xaml | 4 +- NeoUI/NeoUI/Controls/ButtonsStyle.xaml | 11 +- NeoUI/NeoUI/Controls/CalendarStyle.xaml | 213 +++++----- NeoUI/NeoUI/Controls/Cascader.xaml | 10 +- NeoUI/NeoUI/Controls/CheckBoxStyle.xaml | 6 +- NeoUI/NeoUI/Controls/CheckableTag.xaml | 6 +- NeoUI/NeoUI/Controls/ChooseBox.xaml | 7 +- .../Controls/ColorPicker/ColorPicker.xaml | 40 +- NeoUI/NeoUI/Controls/ComboBoxStyle.xaml | 12 +- NeoUI/NeoUI/Controls/DataGridStyle.xaml | 14 +- NeoUI/NeoUI/Controls/DatePickerStyle.xaml | 10 +- .../Controls/Decorations/SlotBorder.xaml | 6 +- NeoUI/NeoUI/Controls/Divider.xaml | 2 +- NeoUI/NeoUI/Controls/ExpanderStyle.xaml | 26 +- NeoUI/NeoUI/Controls/FlattenComboBox.xaml | 4 +- NeoUI/NeoUI/Controls/Hyperlink.xaml | 5 +- NeoUI/NeoUI/Controls/LabelStyle.xaml | 8 +- NeoUI/NeoUI/Controls/ListBoxStyle.xaml | 4 +- NeoUI/NeoUI/Controls/ListViewStyle.xaml | 4 +- NeoUI/NeoUI/Controls/MenuStyle.xaml | 6 +- NeoUI/NeoUI/Controls/Modal/ModalWindow.xaml | 15 +- NeoUI/NeoUI/Controls/MultiTreeView.xaml | 4 +- NeoUI/NeoUI/Controls/NumberBox.xaml | 4 +- .../NeoUI/Controls/PaginationControl.xaml.cs | 2 +- NeoUI/NeoUI/Controls/Pill.xaml | 4 +- NeoUI/NeoUI/Controls/ScrollViewerStyle.xaml | 10 +- NeoUI/NeoUI/Controls/SliderStyle.xaml | 100 +++-- NeoUI/NeoUI/Controls/Toast/ToastControl.xaml | 2 +- NeoUI/NeoUI/Controls/ToggleButtonStyle.xaml | 2 +- NeoUI/NeoUI/Controls/ToolBarStyle.xaml | 4 +- NeoUI/NeoUI/Controls/TreeViewStyle.xaml | 34 +- NeoUI/NeoUI/Controls/UploadArea.xaml | 8 +- NeoUI/NeoUI/Controls/WindowStyle.xaml | 7 +- NeoUI/NeoUI/Themes/ColorPalette/DarkBlue.xaml | 90 ++++- .../NeoUI/Themes/ColorPalette/DarkGreen.xaml | 108 ++++-- .../NeoUI/Themes/ColorPalette/DarkPurple.xaml | 118 ++++-- .../NeoUI/Themes/ColorPalette/LightBlue.xaml | 96 ++++- .../NeoUI/Themes/ColorPalette/LightGreen.xaml | 94 ++++- .../Themes/ColorPalette/LightPurple.xaml | 94 ++++- NeoUI/NeoUI/Themes/Dark.xaml | 365 ++++++++++-------- NeoUI/NeoUI/Themes/Light.xaml | 359 ++++++++++------- NeoUI/NeoUITest/App.xaml | 4 +- NeoUI/NeoUITest/MainWindow.xaml | 2 +- NeoUI/NeoUITest/MainWindow.xaml.cs | 44 ++- Sample/HybridThemeManager.cs | 2 +- .../RvFamily/FamilyProcessorView.xaml | 11 +- .../RvView/ElementControlDock.xaml.cs | 2 +- .../RvView/SectionBoxControllerView.xaml | 18 +- .../RvView/ViewManagerView.xaml | 8 +- .../ShrlAlgoToolkit.RevitAddins.csproj | 2 +- 56 files changed, 1370 insertions(+), 1029 deletions(-) delete mode 100644 NeoUI/NeoUI/Appearance/ResourceDictionaryManager.cs diff --git a/NeoUI/NeoUI/Appearance/ResourceDictionaryManager.cs b/NeoUI/NeoUI/Appearance/ResourceDictionaryManager.cs deleted file mode 100644 index de3d71b..0000000 --- a/NeoUI/NeoUI/Appearance/ResourceDictionaryManager.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System.Collections.ObjectModel; -using System.Reflection; -using NeoUI.Extensions; - -namespace NeoUI.Appearance; - -/// -/// 管理资源字典 -/// -internal class ResourceDictionaryManager -{ - - /// - /// 获取命名空间,例如正在搜索的资源库。 - /// - private string SearchNamespace { get; } = Assembly.GetExecutingAssembly().GetName().Name; - - /// - /// 查找资源 - /// - /// 任何部分的资源名称。 - /// , 如果不存在,返回null - public ResourceDictionary? LookupDictionary(string resourceLookup) - { - Collection? applicationDictionaries = ThemeManager.Current?.Resources.MergedDictionaries; - - if (applicationDictionaries is { Count: 0 }) - { - return null; - } - - if (applicationDictionaries == null) return null; - foreach (var t in applicationDictionaries) - { - string resourceDictionaryUri; - - if (t?.Source != null) - { - resourceDictionaryUri = t.Source.ToString(); - if (resourceDictionaryUri.Contains(SearchNamespace, StringComparison.OrdinalIgnoreCase) && - resourceDictionaryUri.Contains(resourceLookup, StringComparison.OrdinalIgnoreCase)) - { - return t; - } - } - - foreach (var t1 in t!.MergedDictionaries) - { - if (t1?.Source == null) - { - continue; - } - - resourceDictionaryUri = t1.Source.ToString(); - - if (resourceDictionaryUri.Contains(SearchNamespace, StringComparison.OrdinalIgnoreCase) && - resourceDictionaryUri.Contains(resourceLookup, StringComparison.OrdinalIgnoreCase)) - { - return t1; - } - } - } - - return null; - } - - /// - /// 更新应用程序中的资源字典 - /// - /// 要查找的资源名称的一部分 - /// 用于替换的新资源的有效Uri - /// 如果字典Uri已更新则返回true,否则返回false - public bool UpdateDictionary(string resourceLookup, Uri? newResourceUri) - { - // 获取应用程序的合并资源字典集合 - var applicationDictionaries = ThemeManager - .Current?.Resources - .MergedDictionaries; - - // 如果没有资源字典或新的Uri为空,则返回false - if (applicationDictionaries is { Count: 0 } || newResourceUri is null) - { - return false; - } - - // 遍历顶层资源字典 - if (applicationDictionaries == null) return false; - for (var i = 0; i < applicationDictionaries.Count; i++) - { - string sourceUri; - - // 检查当前资源字典是否有Source - if (applicationDictionaries[i]?.Source != null) - { - sourceUri = applicationDictionaries[i].Source.ToString(); - - // 检查资源Uri是否匹配搜索条件 - if (sourceUri.Contains(SearchNamespace, StringComparison.OrdinalIgnoreCase) && - sourceUri.Contains(resourceLookup, StringComparison.OrdinalIgnoreCase)) - { - // 使用新的Uri更新资源字典 - applicationDictionaries[i] = new() { Source = newResourceUri }; - - return true; - } - } - - // 遍历合并的子资源字典 - for (var j = 0; j < applicationDictionaries[i].MergedDictionaries.Count; j++) - { - if (applicationDictionaries[i].MergedDictionaries[j]?.Source == null) - { - continue; - } - - sourceUri = applicationDictionaries[i].MergedDictionaries[j].Source.ToString(); - - // 检查子资源字典Uri是否匹配搜索条件 - if (sourceUri.Contains(SearchNamespace, StringComparison.OrdinalIgnoreCase) && - sourceUri.Contains(resourceLookup, StringComparison.OrdinalIgnoreCase)) - { - // 使用新的Uri更新子资源字典 - applicationDictionaries[i].MergedDictionaries[j] = new ResourceDictionary { Source = newResourceUri }; - return true; - } - } - } - - // 未找到匹配的资源字典,返回false - return false; - } -} diff --git a/NeoUI/NeoUI/Appearance/ThemeManager.cs b/NeoUI/NeoUI/Appearance/ThemeManager.cs index 3967544..a16f90e 100644 --- a/NeoUI/NeoUI/Appearance/ThemeManager.cs +++ b/NeoUI/NeoUI/Appearance/ThemeManager.cs @@ -1,4 +1,6 @@ -using System.IO; +using System.Collections; +using System.Diagnostics; +using System.IO; using System.Reflection; using System.Windows.Media.Animation; @@ -40,10 +42,7 @@ namespace NeoUI.Appearance /// public static string ThemesDictionaryPath => $"pack://application:,,,/{LibraryNamespace};component/Themes/"; - private static ThemeMode _activeThemeMode = ThemeMode.Light; - private static ThemePalette _activeThemePalette = ThemePalette.Blue; private static bool _persistenceEnabled; - private static bool _isSwitching; /// /// 当应用程序的主题模式发生变化时触发的事件。此事件允许订阅者在主题模式更改时执行特定的操作。 @@ -105,6 +104,13 @@ namespace NeoUI.Appearance foreach (var key in AnimatableBrushKeys) { var brush = FindBrushInManagedDictionaries(resources, key); + //if (key == "TextPrimaryBrush") + //{ + // System.Diagnostics.Debug.WriteLine($"--- BAD STATE (Snapshot) ---"); + // System.Diagnostics.Debug.WriteLine($"Brush HashCode: {brush.GetHashCode()}"); + // System.Diagnostics.Debug.WriteLine($"Brush Color: {brush.Color}"); // 这里会显示错误的颜色 + // System.Diagnostics.Debug.WriteLine($"IsFrozen: {brush.IsFrozen}"); // 强烈怀疑这里会是 True + //} if (brush != null) snapshot[key] = brush.Color; } @@ -153,6 +159,7 @@ namespace NeoUI.Appearance if (toColor == fromColor) continue; + Debug.WriteLine($"Animate Key: {key} from {fromColor} to {toColor}"); if (brush.IsFrozen) { // 冻结的 Brush 无法动画,需要复制一个新的 @@ -185,7 +192,7 @@ namespace NeoUI.Appearance To = toColor, Duration = TimeSpan.FromMilliseconds(durationMs), EasingFunction = ThemeEasing, - FillBehavior = FillBehavior.Stop // 动画结束后移除,手动赋值 + FillBehavior = FillBehavior.Stop }; animation.Completed += (_, _) => @@ -223,18 +230,18 @@ namespace NeoUI.Appearance /// 返回当前应用的主题模式,可能的值为 Light 或 Dark。 public static ThemeMode GetAppThemeMode() { - var dict = Application.Current.Resources.MergedDictionaries + var dict = Current.Resources.MergedDictionaries .FirstOrDefault(d => d.Source != null && (d.Source.OriginalString.EndsWith("light.xaml", StringComparison.OrdinalIgnoreCase) || d.Source.OriginalString.EndsWith("dark.xaml", StringComparison.OrdinalIgnoreCase))); if (dict?.Source != null) { var s = dict.Source.OriginalString; if (s.EndsWith("light.xaml", StringComparison.OrdinalIgnoreCase)) - _activeThemeMode = ThemeMode.Light; + ActiveThemeMode = ThemeMode.Light; else if (s.EndsWith("dark.xaml", StringComparison.OrdinalIgnoreCase)) - _activeThemeMode = ThemeMode.Dark; + ActiveThemeMode = ThemeMode.Dark; } - return _activeThemeMode; + return ActiveThemeMode; } /// @@ -243,16 +250,16 @@ namespace NeoUI.Appearance /// 返回当前激活的主题调色板,类型为ThemePalette枚举。 public static ThemePalette GetAppThemePalette() { - var dict = Application.Current.Resources.MergedDictionaries + var dict = Current.Resources.MergedDictionaries .FirstOrDefault(d => d.Source != null && d.Source.OriginalString.IndexOf("/ColorPalette/", StringComparison.OrdinalIgnoreCase) >= 0); if (dict?.Source != null) { var s = Path.GetFileNameWithoutExtension(dict.Source.OriginalString); - if (s.EndsWith("Blue", StringComparison.OrdinalIgnoreCase)) _activeThemePalette = ThemePalette.Blue; - else if (s.EndsWith("Green", StringComparison.OrdinalIgnoreCase)) _activeThemePalette = ThemePalette.Green; - else if (s.EndsWith("Purple", StringComparison.OrdinalIgnoreCase)) _activeThemePalette = ThemePalette.Purple; + if (s.EndsWith("Blue", StringComparison.OrdinalIgnoreCase)) ActiveThemePalette = ThemePalette.Blue; + else if (s.EndsWith("Green", StringComparison.OrdinalIgnoreCase)) ActiveThemePalette = ThemePalette.Green; + else if (s.EndsWith("Purple", StringComparison.OrdinalIgnoreCase)) ActiveThemePalette = ThemePalette.Purple; } - return _activeThemePalette; + return ActiveThemePalette; } #endregion @@ -288,7 +295,7 @@ namespace NeoUI.Appearance /// 返回一个Task对象,代表异步操作的完成状态。 public static Task ApplyThemeAsync(ThemeMode? mode = null, ThemePalette? palette = null, - bool animate = false, + bool animate = true, int animationDurationMs = 350) => InternalApplyThemeAsync(mode, palette, animate, animationDurationMs); @@ -329,83 +336,79 @@ namespace NeoUI.Appearance return; } - if (_isSwitching) return; - _isSwitching = true; - try + var currentMode = GetAppThemeMode(); + var currentPalette = GetAppThemePalette(); + var newMode = mode ?? currentMode; + var newPalette = palette ?? currentPalette; + + bool modeChanged = newMode != currentMode; + bool paletteChanged = newPalette != currentPalette || modeChanged; + if (!modeChanged && !paletteChanged) return; + + var appResources = Current.Resources; + //foreach (var d in appResources.MergedDictionaries) + //{ + // foreach (DictionaryEntry item in d) + // { + // Debug.WriteLine($"{item.Key} = {item.Value}"); + // } + //} + Dictionary? fromColors = null; + if (animate) { - var currentMode = GetAppThemeMode(); - var currentPalette = GetAppThemePalette(); - var newMode = mode ?? currentMode; - var newPalette = palette ?? currentPalette; - - bool modeChanged = newMode != currentMode; - bool paletteChanged = newPalette != currentPalette || modeChanged; - if (!modeChanged && !paletteChanged) return; - - var appResources = Application.Current.Resources; - Dictionary? fromColors = null; - if (animate) - { - RefreshAnimatableKeysFromCurrentManagedDictionaries(appResources, merge: false); - fromColors = TakeColorSnapshot(appResources); - } - - string modeName = newMode == ThemeMode.Dark ? "Dark" : "Light"; - string paletteName = newPalette.ToString(); - var themeUri = new Uri($"{ThemesDictionaryPath}{modeName}.xaml", UriKind.Absolute); - var paletteUri = new Uri($"{ThemesDictionaryPath}ColorPalette/{modeName}{paletteName}.xaml", UriKind.Absolute); - - if (modeChanged) ReplaceOrAddDictionary(themeUri, isTheme: true); - if (paletteChanged) ReplaceOrAddDictionary(paletteUri, isTheme: false); - - if (animate && fromColors != null) - { - RefreshAnimatableKeysFromCurrentManagedDictionaries(appResources, merge: true); - await AnimateToNewTheme(appResources, fromColors, durationMs); - } - - if (modeChanged) - { - _activeThemeMode = newMode; - ThemeModeChanged?.Invoke(newMode); - } - if (paletteChanged) - { - _activeThemePalette = newPalette; - ThemePaletteChanged?.Invoke(newPalette); - } - - if (_persistenceEnabled && (modeChanged || paletteChanged)) - { - try { /* ThemePreferenceStore.Save(_activeThemeMode, _activeThemePalette); */ } - catch { /* 持久化失败静默 */ } - } + RefreshAnimatableKeysFromCurrentManagedDictionaries(appResources, merge: false); + fromColors = TakeColorSnapshot(appResources); } - finally + + string modeName = newMode == ThemeMode.Dark ? "Dark" : "Light"; + string paletteName = newPalette.ToString(); + var themeUri = new Uri($"{ThemesDictionaryPath}{modeName}.xaml", UriKind.Absolute); + var paletteUri = new Uri($"{ThemesDictionaryPath}ColorPalette/{modeName}{paletteName}.xaml", UriKind.Absolute); + + if (modeChanged) ReplaceOrAddDictionary(themeUri, isTheme: true); + if (paletteChanged) ReplaceOrAddDictionary(paletteUri, isTheme: false); + + if (animate && fromColors != null) { - _isSwitching = false; + RefreshAnimatableKeysFromCurrentManagedDictionaries(appResources, merge: true); + await AnimateToNewTheme(appResources, fromColors, durationMs); + } + + if (modeChanged) + { + ActiveThemeMode = newMode; + ThemeModeChanged?.Invoke(newMode); + } + if (paletteChanged) + { + ActiveThemePalette = newPalette; + ThemePaletteChanged?.Invoke(newPalette); + } + + if (_persistenceEnabled && (modeChanged || paletteChanged)) + { + try { ThemePreferenceStore.Save(ActiveThemeMode, ActiveThemePalette); } + catch { /* 持久化失败静默 */ } } } + private static bool IsThemeDict(ResourceDictionary d) + { + var s = d.Source?.ToString(); + return s != null && + s.IndexOf("/Themes/", StringComparison.OrdinalIgnoreCase) >= 0 && + s.IndexOf("/ColorPalette/", StringComparison.OrdinalIgnoreCase) < 0 && + (s.EndsWith("Light.xaml", StringComparison.OrdinalIgnoreCase) || + s.EndsWith("Dark.xaml", StringComparison.OrdinalIgnoreCase)); + } + private static bool IsPaletteDict(ResourceDictionary d) + { + var s = d.Source?.ToString(); + return s != null && s.IndexOf("/Themes/ColorPalette/", StringComparison.OrdinalIgnoreCase) >= 0; + } private static void ReplaceOrAddDictionary(Uri uri, bool isTheme) { - var merged = Application.Current.Resources.MergedDictionaries; - - bool IsThemeDict(ResourceDictionary d) - { - var s = d.Source?.ToString(); - return s != null && - s.IndexOf("/Themes/", StringComparison.OrdinalIgnoreCase) >= 0 && - s.IndexOf("/ColorPalette/", StringComparison.OrdinalIgnoreCase) < 0 && - (s.EndsWith("Light.xaml", StringComparison.OrdinalIgnoreCase) || - s.EndsWith("Dark.xaml", StringComparison.OrdinalIgnoreCase)); - } - - bool IsPaletteDict(ResourceDictionary d) - { - var s = d.Source?.ToString(); - return s != null && s.IndexOf("/Themes/ColorPalette/", StringComparison.OrdinalIgnoreCase) >= 0; - } + var merged = Current.Resources.MergedDictionaries; if (isTheme) { @@ -460,7 +463,7 @@ namespace NeoUI.Appearance public static void SwitchThemeMode() { var target = GetAppThemeMode() == ThemeMode.Light ? ThemeMode.Dark : ThemeMode.Light; - ApplyTheme(target, _activeThemePalette, false); + ApplyTheme(target, ActiveThemePalette, false); } /// @@ -471,7 +474,7 @@ namespace NeoUI.Appearance public static Task SwitchThemeModeAnimatedAsync(int durationMs = 350) { var target = GetAppThemeMode() == ThemeMode.Light ? ThemeMode.Dark : ThemeMode.Light; - return ApplyThemeAsync(target, _activeThemePalette, true, durationMs); + return ApplyThemeAsync(target, ActiveThemePalette, true, durationMs); } /// @@ -481,7 +484,7 @@ namespace NeoUI.Appearance public static void SwitchThemeModeAnimated(int durationMs = 350) { var target = GetAppThemeMode() == ThemeMode.Light ? ThemeMode.Dark : ThemeMode.Light; - ApplyTheme(target, _activeThemePalette, true, durationMs); + ApplyTheme(target, ActiveThemePalette, true, durationMs); } /// @@ -523,7 +526,7 @@ namespace NeoUI.Appearance { System.Diagnostics.Debug.WriteLine("==== " + tag + " MergedDictionaries ===="); int i = 0; - foreach (var d in Application.Current.Resources.MergedDictionaries) + foreach (var d in Current.Resources.MergedDictionaries) System.Diagnostics.Debug.WriteLine($"{i++}: {d.Source}"); } #endif @@ -537,6 +540,11 @@ namespace NeoUI.Appearance private ThemeManager(Application? application) { + //var goodBrush = (SolidColorBrush)Application.Current.Resources["TextPrimaryBrush"]; + //System.Diagnostics.Debug.WriteLine($"--- GOOD STATE ---"); + //System.Diagnostics.Debug.WriteLine($"Brush HashCode: {goodBrush.GetHashCode()}"); + //System.Diagnostics.Debug.WriteLine($"Brush Color: {goodBrush.Color}"); + //System.Diagnostics.Debug.WriteLine($"IsFrozen: {goodBrush.IsFrozen}"); this.application = application; } @@ -562,8 +570,7 @@ namespace NeoUI.Appearance { get { - if (_themeManagerInstance == null) - _themeManagerInstance = new ThemeManager(System.Windows.Application.Current); + _themeManagerInstance ??= new ThemeManager(Application.Current); return _themeManagerInstance; } } @@ -595,10 +602,10 @@ namespace NeoUI.Appearance resources = new ResourceDictionary(); try { - // var themesDictionary = new ThemesDictionary(); - // var controlsDictionary = new ControlsDictionary(); - // resources.MergedDictionaries.Add(themesDictionary); - // resources.MergedDictionaries.Add(controlsDictionary); + var themesDictionary = new ThemesDictionary() { Mode = ActiveThemeMode, Palette = ActiveThemePalette }; + var controlsDictionary = new ControlsDictionary(); + resources.MergedDictionaries.Add(themesDictionary); + resources.MergedDictionaries.Add(controlsDictionary); } catch { /* 忽略初始化异常 */ } return application?.Resources ?? resources; @@ -609,6 +616,15 @@ namespace NeoUI.Appearance resources = value; } } + + /// + /// + /// + public static ThemeMode ActiveThemeMode { get; private set; } = GetAppThemeMode(); + /// + /// + /// + public static ThemePalette ActiveThemePalette { get; private set; } = GetAppThemePalette(); #endregion } } diff --git a/NeoUI/NeoUI/Appearance/ThemesDictionary.cs b/NeoUI/NeoUI/Appearance/ThemesDictionary.cs index bdcdbd9..f776f51 100644 --- a/NeoUI/NeoUI/Appearance/ThemesDictionary.cs +++ b/NeoUI/NeoUI/Appearance/ThemesDictionary.cs @@ -13,19 +13,19 @@ namespace NeoUI.Appearance; [UsableDuringInitialization(true)] public class ThemesDictionary : ResourceDictionary { - private readonly ResourceDictionary _modeDictionary = new ResourceDictionary(); - private readonly ResourceDictionary _paletteDictionary = new ResourceDictionary(); + private readonly ResourceDictionary modeDictionary = new ResourceDictionary(); + private readonly ResourceDictionary paletteDictionary = new ResourceDictionary(); - private ThemeMode? _currentMode; - private ThemePalette? _currentPalette; + private ThemeMode? currentMode; + private ThemePalette? currentPalette; /// /// 构造函数,将内部字典添加到 MergedDictionaries 集合。 /// public ThemesDictionary() { - MergedDictionaries.Add(_modeDictionary); - MergedDictionaries.Add(_paletteDictionary); + MergedDictionaries.Add(modeDictionary); + MergedDictionaries.Add(paletteDictionary); if (DesignerProperties.GetIsInDesignMode(new DependencyObject())) { @@ -43,13 +43,13 @@ public class ThemesDictionary : ResourceDictionary { // 加载 Mode 文件: .../Themes/Light.xaml var defaultModeUri = new Uri($"{ThemeManager.ThemesDictionaryPath}Light.xaml", UriKind.RelativeOrAbsolute); - if (_modeDictionary.Source != defaultModeUri) - _modeDictionary.Source = defaultModeUri; + if (modeDictionary.Source != defaultModeUri) + modeDictionary.Source = defaultModeUri; // 加载 Palette 文件: .../Themes/ColorPalette/LightBlue.xaml var defaultPaletteUri = new Uri($"{ThemeManager.ThemesDictionaryPath}ColorPalette/LightBlue.xaml", UriKind.RelativeOrAbsolute); - if (_paletteDictionary.Source != defaultPaletteUri) - _paletteDictionary.Source = defaultPaletteUri; + if (paletteDictionary.Source != defaultPaletteUri) + paletteDictionary.Source = defaultPaletteUri; return; } @@ -57,25 +57,25 @@ public class ThemesDictionary : ResourceDictionary // 运行时模式:根据当前已有的属性值进行更新。 // 更新 Mode 字典 (只要 Mode 有值就更新) - if (_currentMode.HasValue) + if (currentMode.HasValue) { // 路径示例: /NeoUI;component/Appearance/Themes/Dark.xaml - var modeSourceUri = new Uri($"{ThemeManager.ThemesDictionaryPath}{_currentMode.Value}.xaml", UriKind.RelativeOrAbsolute); - if (_modeDictionary.Source != modeSourceUri) + var modeSourceUri = new Uri($"{ThemeManager.ThemesDictionaryPath}{currentMode.Value}.xaml", UriKind.RelativeOrAbsolute); + if (modeDictionary.Source != modeSourceUri) { - _modeDictionary.Source = modeSourceUri; + modeDictionary.Source = modeSourceUri; } } // 更新 Palette 字典 (必须在 Mode 和 Palette 都有值的情况下才更新) - if (_currentMode.HasValue && _currentPalette.HasValue) + if (currentMode.HasValue && currentPalette.HasValue) { - var paletteName = $"{_currentMode.Value}{_currentPalette.Value}"; + var paletteName = $"{currentMode.Value}{currentPalette.Value}"; // 路径示例: /NeoUI;component/Appearance/Themes/ColorPalette/DarkGreen.xaml var paletteSourceUri = new Uri($"{ThemeManager.ThemesDictionaryPath}ColorPalette/{paletteName}.xaml", UriKind.RelativeOrAbsolute); - if (_paletteDictionary.Source != paletteSourceUri) + if (paletteDictionary.Source != paletteSourceUri) { - _paletteDictionary.Source = paletteSourceUri; + paletteDictionary.Source = paletteSourceUri; } } } @@ -87,9 +87,9 @@ public class ThemesDictionary : ResourceDictionary { set { - if (_currentMode != value) + if (currentMode != value) { - _currentMode = value; + currentMode = value; UpdateSources(); } } @@ -102,9 +102,9 @@ public class ThemesDictionary : ResourceDictionary { set { - if (_currentPalette != value) + if (currentPalette != value) { - _currentPalette = value; + currentPalette = value; UpdateSources(); } } diff --git a/NeoUI/NeoUI/Controls/Alert.xaml b/NeoUI/NeoUI/Controls/Alert.xaml index 0063c99..42a3c62 100644 --- a/NeoUI/NeoUI/Controls/Alert.xaml +++ b/NeoUI/NeoUI/Controls/Alert.xaml @@ -72,10 +72,10 @@ - + - + diff --git a/NeoUI/NeoUI/Controls/Anchor.xaml b/NeoUI/NeoUI/Controls/Anchor.xaml index a069fba..2919cb9 100644 --- a/NeoUI/NeoUI/Controls/Anchor.xaml +++ b/NeoUI/NeoUI/Controls/Anchor.xaml @@ -8,7 +8,7 @@ - - - \ No newline at end of file diff --git a/NeoUI/NeoUI/Controls/Cascader.xaml b/NeoUI/NeoUI/Controls/Cascader.xaml index aca9159..fd7c647 100644 --- a/NeoUI/NeoUI/Controls/Cascader.xaml +++ b/NeoUI/NeoUI/Controls/Cascader.xaml @@ -58,7 +58,7 @@ - + @@ -423,14 +423,14 @@ - + - - + + - + diff --git a/NeoUI/NeoUI/Controls/CheckBoxStyle.xaml b/NeoUI/NeoUI/Controls/CheckBoxStyle.xaml index be445a4..7c48a00 100644 --- a/NeoUI/NeoUI/Controls/CheckBoxStyle.xaml +++ b/NeoUI/NeoUI/Controls/CheckBoxStyle.xaml @@ -7,7 +7,7 @@ - - \ No newline at end of file diff --git a/NeoUI/NeoUI/Controls/ListBoxStyle.xaml b/NeoUI/NeoUI/Controls/ListBoxStyle.xaml index dae5db4..227bf28 100644 --- a/NeoUI/NeoUI/Controls/ListBoxStyle.xaml +++ b/NeoUI/NeoUI/Controls/ListBoxStyle.xaml @@ -184,7 +184,7 @@ - + @@ -232,7 +232,7 @@ - + diff --git a/NeoUI/NeoUI/Controls/ListViewStyle.xaml b/NeoUI/NeoUI/Controls/ListViewStyle.xaml index 30b8a24..34dfeb0 100644 --- a/NeoUI/NeoUI/Controls/ListViewStyle.xaml +++ b/NeoUI/NeoUI/Controls/ListViewStyle.xaml @@ -5,7 +5,7 @@ xmlns:internal="clr-namespace:NeoUI.Converters.Internal" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> @@ -60,6 +61,7 @@ /// - /// 该属性主要用于展示分页控件中每个页面项的具体文本,例如数字或特殊字符(如“<”、“>”)。通过设置不同的Text值,可以自定义分页控件的外观和行为。 + /// 该属性主要用于展示分页控件中每个页面项的具体文本,例如数字或特殊字符(如 <、>)。通过设置不同的Text值,可以自定义分页控件的外观和行为。 /// public string Text { get; set; } diff --git a/NeoUI/NeoUI/Controls/Pill.xaml b/NeoUI/NeoUI/Controls/Pill.xaml index 276e9f3..e63e9d5 100644 --- a/NeoUI/NeoUI/Controls/Pill.xaml +++ b/NeoUI/NeoUI/Controls/Pill.xaml @@ -11,8 +11,8 @@ - - + + diff --git a/NeoUI/NeoUI/Controls/ScrollViewerStyle.xaml b/NeoUI/NeoUI/Controls/ScrollViewerStyle.xaml index 4ea331d..1272f9d 100644 --- a/NeoUI/NeoUI/Controls/ScrollViewerStyle.xaml +++ b/NeoUI/NeoUI/Controls/ScrollViewerStyle.xaml @@ -100,7 +100,7 @@ + + + \ No newline at end of file diff --git a/NeoUI/NeoUI/Themes/ColorPalette/DarkGreen.xaml b/NeoUI/NeoUI/Themes/ColorPalette/DarkGreen.xaml index e40f6a7..b570917 100644 --- a/NeoUI/NeoUI/Themes/ColorPalette/DarkGreen.xaml +++ b/NeoUI/NeoUI/Themes/ColorPalette/DarkGreen.xaml @@ -1,32 +1,54 @@ - - + #57DAA0 - + + #B8E38D + - - - - - - - - - + + #6FDFB2 + - - - - - + #85E6C2 + + + #2FAA74 + + + #406653 + + + + #1A3A2C + + + #6EE0B0 + + + + + + - - - - - + + + + + @@ -37,7 +59,7 @@ - + + + + + \ No newline at end of file diff --git a/NeoUI/NeoUI/Themes/ColorPalette/DarkPurple.xaml b/NeoUI/NeoUI/Themes/ColorPalette/DarkPurple.xaml index e85834a..c809a34 100644 --- a/NeoUI/NeoUI/Themes/ColorPalette/DarkPurple.xaml +++ b/NeoUI/NeoUI/Themes/ColorPalette/DarkPurple.xaml @@ -1,32 +1,54 @@  - + #B67ED6 - - #B8428F + - - - - - - - - - - - - - - - + #B8428F + + + + #BE90D4 + + + #D2B4E4 + + + #9B59B6 + + + #5E376E + + + + #2A1A40 + + + #C49BD9 + + + + + + - - - - - + + + + + @@ -36,4 +58,54 @@ + + + + + + \ No newline at end of file diff --git a/NeoUI/NeoUI/Themes/ColorPalette/LightBlue.xaml b/NeoUI/NeoUI/Themes/ColorPalette/LightBlue.xaml index c1525d2..61457a9 100644 --- a/NeoUI/NeoUI/Themes/ColorPalette/LightBlue.xaml +++ b/NeoUI/NeoUI/Themes/ColorPalette/LightBlue.xaml @@ -1,31 +1,60 @@  - + + #4098FF - + + + #3CD9E0 + - - - + + + #3380E6 + - - - - - - - - - - - + + #1A66CC + + + + #66B2FF + + + + #AFC9E6 + + + + + #D6E9FF + + + + #4098FF + + + + + @@ -39,7 +68,8 @@ - + + + + + + \ No newline at end of file diff --git a/NeoUI/NeoUI/Themes/ColorPalette/LightGreen.xaml b/NeoUI/NeoUI/Themes/ColorPalette/LightGreen.xaml index d69acf9..6310284 100644 --- a/NeoUI/NeoUI/Themes/ColorPalette/LightGreen.xaml +++ b/NeoUI/NeoUI/Themes/ColorPalette/LightGreen.xaml @@ -1,21 +1,45 @@ - - + #34C88A - - #A0DB79 - - - - - - - - - + - + #A0DB79 + + + + #2CAB79 + + + #1F8F65 + + + #1F8F65 + + + #5DD6A4 + + + + #D9F5E6 + + + #009966 + + + @@ -35,7 +59,7 @@ - + + + + + \ No newline at end of file diff --git a/NeoUI/NeoUI/Themes/ColorPalette/LightPurple.xaml b/NeoUI/NeoUI/Themes/ColorPalette/LightPurple.xaml index 5ffdbb2..018a081 100644 --- a/NeoUI/NeoUI/Themes/ColorPalette/LightPurple.xaml +++ b/NeoUI/NeoUI/Themes/ColorPalette/LightPurple.xaml @@ -1,21 +1,45 @@ - - + #9B59B6 - - #D057A8 - - - - - - - - - + - + #D057A8 + + + + #884EA0 + + + #7D3C98 + + + #B27ACC + + + #B27ACC + + + + #EAD9F8 + + + #6C3483 + + + @@ -35,7 +59,7 @@ - + + + + + \ No newline at end of file diff --git a/NeoUI/NeoUI/Themes/Dark.xaml b/NeoUI/NeoUI/Themes/Dark.xaml index aa4f51a..2d56640 100644 --- a/NeoUI/NeoUI/Themes/Dark.xaml +++ b/NeoUI/NeoUI/Themes/Dark.xaml @@ -1,182 +1,235 @@  - - + + + #4A9EFF + - + + #4CAF50 + - - - - - - - #5DADE2 - - - - - - - - - - - - - - - #EC7063 - - - - - - - - - - - - + + #FFB74D + - - #F5B041 - - - - - - - - - - - - - - #5DD68E - - - - - - - - - - - - + + #F44336 + + + + #64B5F6 + + + + #2196F3 + + + + #1976D2 + + + + #1565C0 + + + + #424242 + + + + #1A2332 + + + + #0D47A1 + + + + #F44336 + + + + #D32F2F + + + + #C62828 + + + + #424242 + + + + #2D1B1B + + + + #B71C1C + + + + #FF9800 + + + + #F57C00 + + + + #EF6C00 + + + + #424242 + + + + #2D2517 + + + + #E65100 + + + + #4CAF50 + + + + #388E3C + + + + #2E7D32 + + + + #424242 + + + + #1B2B1F + + + + #1B5E20 + - - - - - - - - - - - + + #10FFFFFF + - - - - - - - - - - - - - - - - + #1A1A1A + - - - - - + #202020 + - + #2A2A2A + + + #60000000 + + + + + #2A2A2A + + + #333333 + + + #3D3D3D + + + #1E3A5F + + + #1F1F1F + + + + + #404040 + + #606060 + + + #505050 + + + + + #40FFFFFF + + + #40000000 + + + + + #FFFFFF + #B0B0B0 + #666666 + #1C1E22 + #80808080 + + + + + + + + + + - - + + - + - - + + - + - - - #C5C9D2 - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/NeoUI/NeoUI/Themes/Light.xaml b/NeoUI/NeoUI/Themes/Light.xaml index 6a0eb54..88e99be 100644 --- a/NeoUI/NeoUI/Themes/Light.xaml +++ b/NeoUI/NeoUI/Themes/Light.xaml @@ -1,115 +1,222 @@  - - - - - - - - - - #3498DB - - - - - - - - - - - - - - + + + #0066CC + + + + #16A085 + + + + #E67E22 + + + + #E74C3C + + + + #3498DB + + + + #3498DB + + + + #2980B9 + + + + #21618C + + + + #BDC3C7 + + + + #EBF5FB + + + + #1B4F72 + + + #E74C3C - - - - - - - - - - - - - + + + + #C0392B + + + + #A93226 + + + + #BDC3C7 + + + + #FADBD8 + + + + #922B21 + + + #F39C12 - - - - - - - - - - - - - - - #2ECC71 - - - - - - - - - - - - + + + + #E67E22 + + + + #D68910 + + + + #BDC3C7 + + + + #FEF9E7 + + + + #B7950B + + + + #27AE60 + + + + #229954 + + + + #1E8449 + + + + #BDC3C7 + + + + #E8F8F5 + + + + #186A3B + - - - - - - - - - - + + #06000000 + - - - - - - - - - - - + #F8F9FA + + + #F1F3F4 + + + #FFFFFF + + + #50000000 + + + + + #FFFFFF + + + #F5F6FA + + + #E8EAF6 + + + #E3F2FD + + + #F5F5F5 + + + + + #E1E4E8 + + + #E5E7EB + - - - - + #D1D5DB + + + + #FFFFFF + + + #1A000000 + + + + + #111827 + #4B5563 + #9CA3AF + #FFFFFF + #6B7280 + + + + + + + + + + - + - - - - - - + @@ -117,60 +224,20 @@ - + + - - - #555A64 - - - - - - - - - - - - - - - - + + + + \ No newline at end of file diff --git a/NeoUI/NeoUITest/App.xaml b/NeoUI/NeoUITest/App.xaml index fc0dd78..ef68d54 100644 --- a/NeoUI/NeoUITest/App.xaml +++ b/NeoUI/NeoUITest/App.xaml @@ -10,14 +10,12 @@ - + - - \ No newline at end of file diff --git a/NeoUI/NeoUITest/MainWindow.xaml b/NeoUI/NeoUITest/MainWindow.xaml index bed969a..1728169 100644 --- a/NeoUI/NeoUITest/MainWindow.xaml +++ b/NeoUI/NeoUITest/MainWindow.xaml @@ -988,7 +988,7 @@ - + diff --git a/NeoUI/NeoUITest/MainWindow.xaml.cs b/NeoUI/NeoUITest/MainWindow.xaml.cs index 7c21523..316c396 100644 --- a/NeoUI/NeoUITest/MainWindow.xaml.cs +++ b/NeoUI/NeoUITest/MainWindow.xaml.cs @@ -1,8 +1,10 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; +using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; @@ -55,7 +57,28 @@ public partial class MainWindow public ICommand ToggleDetailsCommand { get; set; } [RelayCommand] - private void AddArea() { } + private void AddArea() + { + StringBuilder sb = new StringBuilder(); + var dictionary = Application.Current.Resources; + foreach (var res in dictionary.MergedDictionaries) + { + foreach (DictionaryEntry item in res) + { + //sb.AppendLine($"{item.Key} = {item.Value}"); + if (item.Key.ToString() == "TextPrimaryBrush") + { + MessageBox.Show($"TextPrimaryBrush:{item.Value}"); + } + if (item.Key.ToString() == "TextPrimaryBrush") + { + MessageBox.Show($"TextSecondaryBrush:{item.Value}"); + } + } + } + //输出到桌面 + //System.IO.File.WriteAllText(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "resources.txt"), sb.ToString()); + } #endregion #region 静态数据 @@ -278,7 +301,7 @@ public partial class MainWindow #region Modal 事件 private void ShowBasicModal_Click(object sender, RoutedEventArgs e) { - bool? result = Modal.Confirm(this, "Basic Dialog", "This is a basic modal dialog."); + bool? result = Modal.Confirm(this, "默认对话框", "默认对话框"); if (result == true) { MessageBox.Show("User clicked OK!"); @@ -287,7 +310,7 @@ public partial class MainWindow private async void ShowAsyncModal_Click(object sender, RoutedEventArgs e) { - bool? result = Modal.Confirm(this, "Async Dialog", "This dialog will close after a 2-second task.", + bool? result = Modal.Confirm(this, "异步对话框", "对话框将在2s后关闭", async () => { await Task.Delay(2000); @@ -325,20 +348,7 @@ public partial class MainWindow if (sender is not ToggleButton tb) return; var targetMode = tb.IsChecked == true ? ThemeMode.Dark : ThemeMode.Light; - - try - { - _themeAnimating = true; - await ThemeManager.ApplyThemeAsync(targetMode, animate: true, animationDurationMs: 2000); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine("[ThemeToggle] " + ex); - } - finally - { - _themeAnimating = false; - } + await ThemeManager.ApplyThemeAsync(targetMode, animationDurationMs: 800); } private void ColorPalette_OnClick(object sender, RoutedEventArgs e) diff --git a/Sample/HybridThemeManager.cs b/Sample/HybridThemeManager.cs index 4214555..c5495aa 100644 --- a/Sample/HybridThemeManager.cs +++ b/Sample/HybridThemeManager.cs @@ -121,7 +121,7 @@ namespace Sample From = brush.Color, To = toColor, Duration = TimeSpan.FromMilliseconds(400), - EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut } + EasingFunction = new CubicEase { EasingMode = EasingMode.EaseInOut } }; animation.Completed += (s, e) => diff --git a/ShrlAlgoToolkit.RevitAddins/RvFamily/FamilyProcessorView.xaml b/ShrlAlgoToolkit.RevitAddins/RvFamily/FamilyProcessorView.xaml index e2f5a27..15528d5 100644 --- a/ShrlAlgoToolkit.RevitAddins/RvFamily/FamilyProcessorView.xaml +++ b/ShrlAlgoToolkit.RevitAddins/RvFamily/FamilyProcessorView.xaml @@ -9,6 +9,7 @@ x:Class="ShrlAlgoToolkit.RevitAddins.RvFamily.FamilyProcessorView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:drawing="clr-namespace:System.Drawing;assembly=System.Drawing" xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:local="clr-namespace:ShrlAlgoToolkit.RevitAddins.RvFamily" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" @@ -63,20 +64,20 @@ Grid.Row="1" VerticalAlignment="Center"> - + + TextOptions.TextFormattingMode="Display" + ui:InputAssist.Placeholder="保存路径" />