Update MW_AutoTheme.cs

This commit is contained in:
PrefacedCorg
2026-04-11 17:03:20 +08:00
parent b56f99fff9
commit bb82eb4891
+102 -330
View File
@@ -14,19 +14,18 @@ namespace Ink_Canvas
{
public partial class MainWindow : Window
{
/// <summary>
/// 浮动栏前景色,根据当前主题动态更新。
/// </summary>
private const string ThemeLight = "Light";
private const string ThemeDark = "Dark";
private const string LightThemePath = "Resources/Styles/Light.xaml";
private const string DarkThemePath = "Resources/Styles/Dark.xaml";
private const string DrawShapeImagePath = "Resources/DrawShapeImageDictionary.xaml";
private const string SeewoImagePath = "Resources/SeewoImageDictionary.xaml";
private const string IconImagePath = "Resources/IconImageDictionary.xaml";
private Color FloatBarForegroundColor;
/// <summary>
/// 应用并切换到指定的主题("Light" 或 "Dark"),更新主题资源并刷新相关 UI 元素以反映主题变化。
/// </summary>
/// <param name="theme">主题标识,支持 "Light" 或 "Dark"(区分大小写)。</param>
/// <param name="autoSwitchIcon">若为 true,则根据主题自动切换并保存浮动工具栏的图标设置。</param>
private void SetTheme(string theme, bool autoSwitchIcon = false)
{
// 清理现有的主题资源
var resourcesToRemove = new List<ResourceDictionary>();
foreach (var dict in Application.Current.Resources.MergedDictionaries)
{
@@ -43,195 +42,85 @@ namespace Ink_Canvas
Application.Current.Resources.MergedDictionaries.Remove(dict);
}
if (theme == "Light")
var isLightTheme = theme == ThemeLight;
var themePath = isLightTheme ? LightThemePath : DarkThemePath;
var elementTheme = isLightTheme ? ElementTheme.Light : ElementTheme.Dark;
var rd1 = new ResourceDictionary { Source = new Uri(themePath, UriKind.Relative) };
Application.Current.Resources.MergedDictionaries.Add(rd1);
_ = Task.Run(async () =>
{
// 先加载主题
var rd1 = new ResourceDictionary
await Task.Delay(100);
Dispatcher.Invoke(() =>
{
Source = new Uri("Resources/Styles/Light.xaml", UriKind.Relative)
};
Application.Current.Resources.MergedDictionaries.Add(rd1);
// 异步加载图形资源,避免阻塞启动
_ = Task.Run(async () =>
{
await Task.Delay(100);
Dispatcher.Invoke(() =>
{
var rd2 = new ResourceDictionary
{
Source = new Uri("Resources/DrawShapeImageDictionary.xaml", UriKind.Relative)
};
Application.Current.Resources.MergedDictionaries.Add(rd2);
var rd3 = new ResourceDictionary
{
Source = new Uri("Resources/SeewoImageDictionary.xaml", UriKind.Relative)
};
Application.Current.Resources.MergedDictionaries.Add(rd3);
var rd4 = new ResourceDictionary
{
Source = new Uri("Resources/IconImageDictionary.xaml", UriKind.Relative)
};
Application.Current.Resources.MergedDictionaries.Add(rd4);
});
LoadImageResourceDictionary(DrawShapeImagePath);
LoadImageResourceDictionary(SeewoImagePath);
LoadImageResourceDictionary(IconImagePath);
});
});
ThemeManager.SetRequestedTheme(window, ElementTheme.Light);
ThemeManager.SetRequestedTheme(window, elementTheme);
InitializeFloatBarForegroundColor();
InitializeFloatBarForegroundColor();
RefreshQuickPanelIcons();
RefreshStrokeSelectionIcons();
RefreshImageSelectionIcons();
RefreshGestureButtonIcon();
RefreshFloatingBarHighlightColors();
// 刷新快速面板图标
RefreshQuickPanelIcons();
// 刷新墨迹选中栏图标
RefreshStrokeSelectionIcons();
// 刷新图片选中栏图标
RefreshImageSelectionIcons();
// 刷新手势按钮图标
RefreshGestureButtonIcon();
RefreshFloatingBarHighlightColors();
if (autoSwitchIcon)
{
AutoSwitchFloatingBarIconForTheme("Light");
}
// 强制刷新UI
window.InvalidateVisual();
// 通知其他窗口刷新主题
RefreshOtherWindowsTheme();
}
else if (theme == "Dark")
if (autoSwitchIcon)
{
// 先加载主题
var rd1 = new ResourceDictionary { Source = new Uri("Resources/Styles/Dark.xaml", UriKind.Relative) };
Application.Current.Resources.MergedDictionaries.Add(rd1);
// 异步加载图形资源,避免阻塞启动
_ = Task.Run(async () =>
{
await Task.Delay(100);
Dispatcher.Invoke(() =>
{
var rd2 = new ResourceDictionary
{
Source = new Uri("Resources/DrawShapeImageDictionary.xaml", UriKind.Relative)
};
Application.Current.Resources.MergedDictionaries.Add(rd2);
var rd3 = new ResourceDictionary
{
Source = new Uri("Resources/SeewoImageDictionary.xaml", UriKind.Relative)
};
Application.Current.Resources.MergedDictionaries.Add(rd3);
var rd4 = new ResourceDictionary
{
Source = new Uri("Resources/IconImageDictionary.xaml", UriKind.Relative)
};
Application.Current.Resources.MergedDictionaries.Add(rd4);
});
});
ThemeManager.SetRequestedTheme(window, ElementTheme.Dark);
InitializeFloatBarForegroundColor();
// 刷新快速面板图标
RefreshQuickPanelIcons();
// 刷新墨迹选中栏图标
RefreshStrokeSelectionIcons();
// 刷新图片选中栏图标
RefreshImageSelectionIcons();
// 刷新手势按钮图标
RefreshGestureButtonIcon();
RefreshFloatingBarHighlightColors();
if (autoSwitchIcon)
{
AutoSwitchFloatingBarIconForTheme("Dark");
}
// 强制刷新UI
window.InvalidateVisual();
// 通知其他窗口刷新主题
RefreshOtherWindowsTheme();
AutoSwitchFloatingBarIconForTheme(theme);
}
window.InvalidateVisual();
RefreshOtherWindowsTheme();
}
void LoadImageResourceDictionary(string path)
{
var rd = new ResourceDictionary { Source = new Uri(path, UriKind.Relative) };
Application.Current.Resources.MergedDictionaries.Add(rd);
}
/// <summary>
/// 初始化FloatBarForegroundColor,从当前主题资源中加载颜色
/// </summary>
private void InitializeFloatBarForegroundColor()
{
try
{
FloatBarForegroundColor = (Color)Application.Current.FindResource("FloatBarForegroundColor");
// 强制刷新浮动工具栏按钮颜色
RefreshFloatingBarButtonColors();
}
catch (Exception)
{
// 如果无法从资源中加载,使用默认颜色
FloatBarForegroundColor = Color.FromRgb(0, 0, 0);
}
}
/// <summary>
/// 刷新快速面板图标
/// </summary>
private void RefreshQuickPanelIcons()
{
try
{
if (LeftUnFoldButtonQuickPanel != null)
{
LeftUnFoldButtonQuickPanel.InvalidateVisual();
}
if (RightUnFoldButtonQuickPanel != null)
{
RightUnFoldButtonQuickPanel.InvalidateVisual();
}
if (LeftSidePanel != null)
{
LeftSidePanel.InvalidateVisual();
}
if (RightSidePanel != null)
{
RightSidePanel.InvalidateVisual();
}
LeftUnFoldButtonQuickPanel?.InvalidateVisual();
RightUnFoldButtonQuickPanel?.InvalidateVisual();
LeftSidePanel?.InvalidateVisual();
RightSidePanel?.InvalidateVisual();
}
catch (Exception)
{
}
}
/// <summary>
/// 刷新浮动栏高光条颜色
/// </summary>
private void RefreshFloatingBarHighlightColors()
{
try
{
if (FloatingbarSelectionBG != null && FloatingbarSelectionBG.Visibility == Visibility.Visible)
{
// 根据主题设置高光颜色
bool isDarkTheme = IsCurrentThemeDark();
Color highlightBackgroundColor;
Color highlightBarColor;
bool isDarkTheme = Settings.Appearance.Theme == 1 ||
(Settings.Appearance.Theme == 2 && !IsSystemThemeLight());
if (isDarkTheme)
{
@@ -244,7 +133,6 @@ namespace Ink_Canvas
highlightBarColor = Color.FromRgb(37, 99, 235);
}
// 设置高光背景颜色
FloatingbarSelectionBG.Background = new SolidColorBrush(highlightBackgroundColor);
if (FloatingbarSelectionBG.Child is System.Windows.Controls.Canvas canvas && canvas.Children.Count > 0)
{
@@ -261,74 +149,50 @@ namespace Ink_Canvas
}
}
/// <summary>
/// 刷新浮动工具栏按钮颜色
/// </summary>
private bool IsCurrentThemeDark()
{
return Settings.Appearance.Theme == 1 ||
(Settings.Appearance.Theme == 2 && !IsSystemThemeLight());
}
private void RefreshFloatingBarButtonColors()
{
try
{
// 根据主题选择高光颜色
Color selectedColor;
bool isDarkTheme = Settings.Appearance.Theme == 1 ||
(Settings.Appearance.Theme == 2 && !IsSystemThemeLight());
SymbolIconDelete.Icon.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.DeleteIcon);
ShapeDrawFloatingBarBtn.Icon.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.ShapesIcon);
SymbolIconUndo.Icon.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.UndoIcon);
SymbolIconRedo.Icon.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.RedoIcon);
CursorWithDelFloatingBarBtn.Icon.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.CursorWithDelFloatingBarBtnIcon);
WhiteboardFloatingBarBtn.Icon.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.WhiteboardFloatingBarBtnIcon);
ToolsFloatingBarBtn.Icon.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.ToolsFloatingBarBtnIcon);
Fold_Icon.Icon.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.FoldIcon);
if (isDarkTheme)
{
selectedColor = Color.FromRgb(102, 204, 255);
}
else
{
selectedColor = Color.FromRgb(30, 58, 138);
}
bool isDarkTheme = IsCurrentThemeDark();
Color selectedColor = isDarkTheme ? Color.FromRgb(102, 204, 255) : Color.FromRgb(30, 58, 138);
SetAllFloatingBarButtonsToColor(FloatBarForegroundColor);
SymbolIconDelete.Icon.Brush = new SolidColorBrush(Color.FromRgb(239, 68, 68));
// 根据当前模式设置按钮颜色
switch (_currentToolMode)
{
case "cursor":
Cursor_Icon.Icon.Brush = new SolidColorBrush(selectedColor);
Pen_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
EraserByStrokes_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
Eraser_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
SymbolIconSelect.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
break;
case "pen":
case "color":
Cursor_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
Pen_Icon.Icon.Brush = new SolidColorBrush(selectedColor);
EraserByStrokes_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
Eraser_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
SymbolIconSelect.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
break;
case "eraser":
Cursor_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
Pen_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
EraserByStrokes_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
Eraser_Icon.Icon.Brush = new SolidColorBrush(selectedColor);
SymbolIconSelect.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
break;
case "eraserByStrokes":
Cursor_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
Pen_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
EraserByStrokes_Icon.Icon.Brush = new SolidColorBrush(selectedColor);
Eraser_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
SymbolIconSelect.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
break;
case "select":
Cursor_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
Pen_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
EraserByStrokes_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
Eraser_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
SymbolIconSelect.Icon.Brush = new SolidColorBrush(selectedColor);
break;
default:
// 默认情况,所有按钮都使用主题颜色
Cursor_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
Pen_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
EraserByStrokes_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
Eraser_Icon.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
SymbolIconSelect.Icon.Brush = new SolidColorBrush(FloatBarForegroundColor);
break;
}
}
catch (Exception)
@@ -336,79 +200,60 @@ namespace Ink_Canvas
}
}
/// <summary>
/// 处理系统主题偏好变化事件,根据当前设置更新应用主题。
/// </summary>
/// <param name="sender">事件发送者。</param>
/// <param name="e">用户偏好变化事件参数。</param>
/// <remarks>
/// 操作包括:
/// 1. 根据当前主题设置(Settings.Appearance.Theme)决定使用哪种主题
/// 2. 如果设置为0(浅色主题),则设置为Light主题
/// 3. 如果设置为1(深色主题),则设置为Dark主题
/// 4. 如果设置为2(跟随系统主题),则根据系统主题设置应用相应的主题
/// </remarks>
void SetAllFloatingBarButtonsToColor(Color color)
{
var brush = new SolidColorBrush(color);
Cursor_Icon.Icon.Brush = brush;
Pen_Icon.Icon.Brush = brush;
EraserByStrokes_Icon.Icon.Brush = brush;
Eraser_Icon.Icon.Brush = brush;
SymbolIconSelect.Icon.Brush = brush;
ShapeDrawFloatingBarBtn.Icon.Brush = brush;
SymbolIconUndo.Icon.Brush = brush;
SymbolIconRedo.Icon.Brush = brush;
CursorWithDelFloatingBarBtn.Icon.Brush = brush;
WhiteboardFloatingBarBtn.Icon.Brush = brush;
ToolsFloatingBarBtn.Icon.Brush = brush;
Fold_Icon.Icon.Brush = brush;
}
private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
{
switch (Settings.Appearance.Theme)
{
case 0:
SetTheme("Light");
SetTheme(ThemeLight);
break;
case 1:
SetTheme("Dark");
SetTheme(ThemeDark);
break;
case 2:
if (IsSystemThemeLight()) SetTheme("Light");
else SetTheme("Dark");
SetTheme(IsSystemThemeLight() ? ThemeLight : ThemeDark);
break;
}
}
/// <summary>
/// 检查系统主题是否为浅色主题。
/// </summary>
/// <returns>系统主题为浅色返回true,深色返回false。</returns>
/// <remarks>
/// 操作包括:
/// 1. 从注册表中读取系统主题设置
/// 2. 检查"SystemUsesLightTheme"键的值
/// 3. 如果值为1,则表示系统使用浅色主题
/// 4. 捕获可能的异常,确保方法不会因异常而崩溃
/// </remarks>
private bool IsSystemThemeLight()
{
var light = false;
try
{
var registryKey = Registry.CurrentUser;
var themeKey =
registryKey.OpenSubKey("software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
var keyValue = 0;
if (themeKey != null) keyValue = (int)themeKey.GetValue("SystemUsesLightTheme");
if (keyValue == 1) light = true;
var themeKey = registryKey.OpenSubKey("software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
if (themeKey != null)
{
int keyValue = (int)themeKey.GetValue("SystemUsesLightTheme");
return keyValue == 1;
}
}
catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }
return light;
return false;
}
/// <summary>
/// 根据主题自动切换浮动栏图标
/// </summary>
private void AutoSwitchFloatingBarIconForTheme(string theme)
{
try
{
if (theme == "Light")
{
Settings.Appearance.FloatingBarImg = 0;
}
else if (theme == "Dark")
{
Settings.Appearance.FloatingBarImg = 3;
}
Settings.Appearance.FloatingBarImg = theme == ThemeLight ? 0 : 3;
UpdateFloatingBarIcon();
UpdateFloatingBarIconComboBox();
}
@@ -417,9 +262,6 @@ namespace Ink_Canvas
}
}
/// <summary>
/// 更新设置界面中的浮动栏图标选择下拉框显示
/// </summary>
private void UpdateFloatingBarIconComboBox()
{
try
@@ -434,94 +276,45 @@ namespace Ink_Canvas
}
}
/// <summary>
/// 刷新墨迹选中栏图标
/// </summary>
private void RefreshStrokeSelectionIcons()
{
try
{
if (BorderStrokeSelectionControl != null)
{
// 强制刷新墨迹选中栏的视觉状态
BorderStrokeSelectionControl.InvalidateVisual();
// 刷新墨迹选中栏内的所有图标
var viewbox = BorderStrokeSelectionControl.Child as Viewbox;
if (viewbox?.Child is ui.SimpleStackPanel stackPanel)
{
RefreshStrokeSelectionIconsRecursive(stackPanel);
RefreshIconsRecursive(stackPanel);
}
}
}
catch (Exception)
{
// 忽略异常,确保主题切换不会因为图标刷新失败而中断
}
}
/// <summary>
/// 递归刷新墨迹选中栏内的图标
/// </summary>
private void RefreshStrokeSelectionIconsRecursive(System.Windows.Controls.Panel panel)
{
try
{
foreach (var child in panel.Children)
{
if (child is Image image)
{
// 强制刷新图像
image.InvalidateVisual();
}
else if (child is System.Windows.Controls.Panel childPanel)
{
// 递归处理子面板
RefreshStrokeSelectionIconsRecursive(childPanel);
}
else if (child is Border border && border.Child is System.Windows.Controls.Panel borderPanel)
{
// 处理Border内的面板
RefreshStrokeSelectionIconsRecursive(borderPanel);
}
}
}
catch (Exception)
{
// 忽略异常
}
}
/// <summary>
/// 刷新图片选中栏图标
/// </summary>
private void RefreshImageSelectionIcons()
{
try
{
if (BorderImageSelectionControl != null)
{
// 强制刷新图片选中栏的视觉状态
BorderImageSelectionControl.InvalidateVisual();
// 刷新图片选中栏内的所有图标
var viewbox = BorderImageSelectionControl.Child as Viewbox;
if (viewbox?.Child is ui.SimpleStackPanel stackPanel)
{
RefreshImageSelectionIconsRecursive(stackPanel);
RefreshIconsRecursive(stackPanel);
}
}
}
catch (Exception)
{
// 忽略异常,确保主题切换不会因为图标刷新失败而中断
}
}
/// <summary>
/// 递归刷新图片选中栏内的图标
/// </summary>
private void RefreshImageSelectionIconsRecursive(System.Windows.Controls.Panel panel)
private void RefreshIconsRecursive(System.Windows.Controls.Panel panel)
{
try
{
@@ -529,22 +322,18 @@ namespace Ink_Canvas
{
if (child is Image image)
{
// 强制刷新图像
image.InvalidateVisual();
}
else if (child is System.Windows.Controls.Panel childPanel)
{
// 递归处理子面板
RefreshImageSelectionIconsRecursive(childPanel);
RefreshIconsRecursive(childPanel);
}
else if (child is Border border && border.Child is System.Windows.Controls.Panel borderPanel)
{
// 处理Border内的面板
RefreshImageSelectionIconsRecursive(borderPanel);
RefreshIconsRecursive(borderPanel);
}
else if (child is Grid grid)
{
// 处理Grid内的子元素
foreach (var gridChild in grid.Children)
{
if (gridChild is Image gridImage)
@@ -557,18 +346,13 @@ namespace Ink_Canvas
}
catch (Exception)
{
// 忽略异常
}
}
/// <summary>
/// 刷新手势按钮图标
/// </summary>
private void RefreshGestureButtonIcon()
{
try
{
// 调用手势按钮颜色和图标更新方法,该方法会根据当前主题和手势状态设置正确的图标
CheckEnableTwoFingerGestureBtnColorPrompt();
}
catch (Exception)
@@ -576,14 +360,10 @@ namespace Ink_Canvas
}
}
/// <summary>
/// 刷新其他窗口的主题
/// </summary>
private void RefreshOtherWindowsTheme()
{
try
{
// 刷新所有打开的窗口
foreach (Window window in Application.Current.Windows)
{
if (window is CountdownTimerWindow timerWindow)
@@ -600,20 +380,12 @@ namespace Ink_Canvas
}
}
// 刷新计时器控件
if (TimerControl != null)
{
TimerControl.RefreshTheme();
}
if (MinimizedTimerControl != null)
{
MinimizedTimerControl.RefreshTheme();
}
TimerControl?.RefreshTheme();
MinimizedTimerControl?.RefreshTheme();
}
catch (Exception)
{
}
}
}
}
}