using Ink_Canvas.Windows.SettingsViews;
using iNKORE.UI.WPF.Helpers;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
namespace Ink_Canvas.Windows
{
public partial class SettingsWindow : Window
{
private MainWindow _mainWindow;
///
/// 初始化设置窗口的 UI、事件和面板并加载初始状态与主题。
///
///
/// 构造函数完成以下工作:获取主窗口引用,注册搜索与菜单事件,构建并绑定侧栏条目,挂接各设置面板的滚动/阴影事件,初始化面板配置,设置初始选中项与主题状态,为自定义滑块添加触摸支持,预加载所有面板设置,并多次应用主题以确保视觉元素正确呈现(包含延迟再应用以修正标题栏等)。
///
public SettingsWindow()
{
InitializeComponent();
// 获取 MainWindow 实例
_mainWindow = Application.Current.MainWindow as MainWindow;
// 初始化各个组件
InitializeSearchPanelEvents();
InitializeMenuEvents();
InitializeSidebarItems();
SubscribePanelEvents();
InitializeThemeState();
// 为自定义滑块控件添加触摸支持
AddTouchSupportToCustomSliders();
// 先应用主题,确保标题栏等元素正确显示
ApplyTheme();
// 加载所有面板的设置
LoadAllPanelsSettings();
// 通知所有面板应用主题
ApplyThemeToAllPanels();
// 延迟再次应用主题,确保所有元素都正确应用主题(特别是标题栏)
Dispatcher.BeginInvoke(new Action(() =>
{
ApplyTheme();
ApplyThemeToAllPanels();
}), System.Windows.Threading.DispatcherPriority.Loaded);
}
///
/// 通知所有已注册的设置面板应用当前主题配置,使各面板更新其视觉样式以匹配窗口主题。
///
///
/// 对每个面板尝试通过反射调用其 `ApplyTheme` 方法;如果某面板不存在该方法则会跳过,调用过程中发生的异常会被捕获并写入调试输出,但不会中断对其它面板的处理。
///
private void ApplyThemeToAllPanels()
{
try
{
bool isDarkTheme = MainWindow.Settings?.Appearance != null &&
(MainWindow.Settings.Appearance.Theme == 1 ||
(MainWindow.Settings.Appearance.Theme == 2 && !IsSystemThemeLight()));
// 使用反射调用所有面板的 ApplyTheme 方法(如果存在)
var panels = new UserControl[]
{
SecurityPanel, UpdateCenterPanel, StartupPanel, CanvasAndInkPanel, GesturesPanel, InkRecognitionPanel,
ThemePanel, ShortcutsPanel, CrashActionPanel, PowerPointPanel,
AutomationPanel, LuckyRandomPanel, AdvancedPanel, SnapshotPanel,
SettingsAboutPanel, AppearancePanel, SearchPanelControl
};
foreach (var panel in panels)
{
if (panel != null)
{
var method = panel.GetType().GetMethod("ApplyTheme",
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (method != null)
{
try
{
method.Invoke(panel, null);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"应用主题到 {panel.GetType().Name} 时出错: {ex.Message}");
}
}
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"通知面板应用主题时出错: {ex.Message}");
}
}
///
/// 应用主题
///
public void ApplyTheme()
{
try
{
if (MainWindow.Settings?.Appearance == null) return;
bool isDarkTheme = MainWindow.Settings.Appearance.Theme == 1 ||
(MainWindow.Settings.Appearance.Theme == 2 && !IsSystemThemeLight());
if (isDarkTheme)
{
if (MainBorder != null)
{
MainBorder.Background = new SolidColorBrush(Color.FromRgb(43, 43, 43));
MainBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(0, 120, 215));
}
if (SidebarBorder != null)
{
SidebarBorder.Background = ThemeHelper.GetBackgroundSecondaryBrush(); // Windows 系统次要背景 #191919
SidebarBorder.BorderBrush = ThemeHelper.GetBorderPrimaryBrush(); // Windows 系统边框
}
if (SearchButtonBorder != null)
{
SearchButtonBorder.Background = ThemeHelper.GetButtonBackgroundBrush(); // Windows 系统按钮背景
// 更新搜索按钮图标颜色
UpdateButtonIconColor(SearchButtonBorder, true);
}
if (MenuButtonBorder != null)
{
MenuButtonBorder.Background = ThemeHelper.GetButtonBackgroundBrush(); // Windows 系统按钮背景
// 更新菜单按钮图标颜色
UpdateButtonIconColor(MenuButtonBorder, true);
}
if (TitleTextBlock != null)
{
TitleTextBlock.Foreground = ThemeHelper.GetTextPrimaryBrush(); // Windows 系统主文字颜色
}
if (MenuButtonContextMenu != null)
{
MenuButtonContextMenu.Background = ThemeHelper.GetBackgroundSecondaryBrush(); // Windows 系统菜单背景
MenuButtonContextMenu.BorderBrush = ThemeHelper.GetBorderPrimaryBrush(); // Windows 系统边框
// 更新上下文菜单中的图标和文字颜色
UpdateContextMenuTheme(MenuButtonContextMenu, true);
}
if (SettingsWindowTitle != null)
{
SettingsWindowTitle.Foreground = ThemeHelper.GetTextPrimaryBrush(); // Windows 系统主文字颜色
}
if (TopBarBorder != null)
{
TopBarBorder.Background = ThemeHelper.GetBackgroundPrimaryBrush(); // Windows 系统主背景
}
// 更新内部标题栏背景 - 使用直接访问而不是 FindDescendantByName
// TopBarBackgroundBorder 是 TopBarBorder 的直接子元素
if (TopBarBorder != null && TopBarBorder.Child is Border topBarBackgroundBorder)
{
topBarBackgroundBorder.Background = ThemeHelper.GetBackgroundPrimaryBrush(); // Windows 系统主背景
}
// 如果上面的方法找不到,尝试使用 FindDescendantByName 作为备用
var topBarBackgroundBorderFallback = this.FindDescendantByName("TopBarBackgroundBorder") as Border;
if (topBarBackgroundBorderFallback != null)
{
topBarBackgroundBorderFallback.Background = ThemeHelper.GetBackgroundPrimaryBrush(); // Windows 系统主背景
}
// 更新侧边栏项目文本颜色
foreach (var item in SidebarItems)
{
// 通过反射或直接访问来更新文本颜色
// 这里需要在 XAML 中绑定或通过其他方式更新
}
// 更新滚动条样式 - 参考 Windows 系统设置
var scrollBarTrack = this.FindDescendantByName("ScrollBarBorderTrackBackground") as Border;
if (scrollBarTrack != null)
{
scrollBarTrack.Background = ThemeHelper.GetScrollBarTrackBrush(); // Windows 系统滚动条轨道
scrollBarTrack.Opacity = 0.3;
}
// 更新侧边栏项目主题
foreach (var item in SidebarItems)
{
item.IsDarkTheme = true;
}
CollectionViewSource.GetDefaultView(SidebarItems).Refresh();
// 更新图标颜色
UpdateIconColors(true);
}
else
{
if (MainBorder != null)
{
MainBorder.Background = new SolidColorBrush(Color.FromRgb(255, 255, 255));
MainBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(53, 132, 228));
}
if (SidebarBorder != null)
{
SidebarBorder.Background = new SolidColorBrush(Color.FromRgb(235, 235, 235));
SidebarBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(225, 225, 225));
}
if (SearchButtonBorder != null)
{
SearchButtonBorder.Background = new SolidColorBrush(Color.FromRgb(217, 217, 217));
// 更新搜索按钮图标颜色
UpdateButtonIconColor(SearchButtonBorder, false);
}
if (MenuButtonBorder != null)
{
MenuButtonBorder.Background = new SolidColorBrush(Color.FromRgb(217, 217, 217));
// 更新菜单按钮图标颜色
UpdateButtonIconColor(MenuButtonBorder, false);
}
if (TitleTextBlock != null)
{
TitleTextBlock.Foreground = new SolidColorBrush(Color.FromRgb(46, 52, 54));
}
if (MenuButtonContextMenu != null)
{
MenuButtonContextMenu.Background = new SolidColorBrush(Color.FromRgb(255, 255, 255));
MenuButtonContextMenu.BorderBrush = new SolidColorBrush(Color.FromRgb(211, 211, 211));
// 更新上下文菜单中的图标和文字颜色
UpdateContextMenuTheme(MenuButtonContextMenu, false);
}
if (SettingsWindowTitle != null)
{
SettingsWindowTitle.Foreground = new SolidColorBrush(Color.FromRgb(46, 52, 54));
}
if (TopBarBorder != null)
{
TopBarBorder.Background = new SolidColorBrush(Color.FromRgb(250, 250, 250));
}
// 更新内部标题栏背景 - 使用直接访问而不是 FindDescendantByName
// TopBarBackgroundBorder 是 TopBarBorder 的直接子元素
if (TopBarBorder != null && TopBarBorder.Child is Border topBarBackgroundBorder)
{
topBarBackgroundBorder.Background = new SolidColorBrush(Color.FromRgb(250, 250, 250));
}
// 如果上面的方法找不到,尝试使用 FindDescendantByName 作为备用
var topBarBackgroundBorderFallback = this.FindDescendantByName("TopBarBackgroundBorder") as Border;
if (topBarBackgroundBorderFallback != null)
{
topBarBackgroundBorderFallback.Background = new SolidColorBrush(Color.FromRgb(250, 250, 250));
}
// 更新滚动条样式
var scrollBarTrack = this.FindDescendantByName("ScrollBarBorderTrackBackground") as Border;
if (scrollBarTrack != null)
{
scrollBarTrack.Background = ThemeHelper.GetScrollBarTrackBrush(); // Windows 系统滚动条轨道
scrollBarTrack.Opacity = 0;
}
// 更新侧边栏项目主题
foreach (var item in SidebarItems)
{
item.IsDarkTheme = false;
}
CollectionViewSource.GetDefaultView(SidebarItems).Refresh();
// 更新图标颜色
UpdateIconColors(false);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"应用主题时出错: {ex.Message}");
}
}
///
/// 更新所有图标颜色以适配主题
///
private void UpdateIconColors(bool isDarkTheme)
{
try
{
// 根据主题选择颜色
Color iconColor = isDarkTheme
? Color.FromRgb(243, 243, 243) // 深色主题使用浅色图标 #F3F3F3
: Color.FromRgb(34, 34, 34); // 浅色主题使用深色图标 #222222
// 更新每个侧边栏项目的图标
foreach (var item in SidebarItems)
{
if (item.IconSource is DrawingImage drawingImage &&
drawingImage.Drawing is DrawingGroup drawingGroup)
{
// 克隆并更新图标
var clonedDrawing = CloneDrawingGroup(drawingGroup, iconColor);
item.IconSource = new DrawingImage { Drawing = clonedDrawing };
}
}
CollectionViewSource.GetDefaultView(SidebarItems).Refresh();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"更新图标颜色时出错: {ex.Message}");
}
}
///
/// 克隆 DrawingGroup 并更新颜色
///
private DrawingGroup CloneDrawingGroup(DrawingGroup source, Color newColor)
{
var cloned = new DrawingGroup();
cloned.ClipGeometry = source.ClipGeometry?.Clone();
cloned.Opacity = source.Opacity;
cloned.Transform = source.Transform?.Clone();
foreach (var drawing in source.Children)
{
if (drawing is GeometryDrawing geometryDrawing)
{
var clonedGeometry = geometryDrawing.Geometry?.Clone();
var clonedBrush = CloneBrush(geometryDrawing.Brush, newColor);
var clonedPen = geometryDrawing.Pen != null
? ClonePen(geometryDrawing.Pen, newColor)
: null;
cloned.Children.Add(new GeometryDrawing(clonedBrush, clonedPen, clonedGeometry));
}
else if (drawing is DrawingGroup subGroup)
{
cloned.Children.Add(CloneDrawingGroup(subGroup, newColor));
}
else
{
// 对于其他类型的 Drawing,尝试克隆
cloned.Children.Add(drawing);
}
}
return cloned;
}
///
/// 克隆 Brush 并更新颜色
///
private Brush CloneBrush(Brush source, Color newColor)
{
if (source is SolidColorBrush solidBrush)
{
// 检查是否是深色(需要更新的颜色)
var originalColor = solidBrush.Color;
if (originalColor.R == 34 && originalColor.G == 34 && originalColor.B == 34) // #222222
{
return new SolidColorBrush(newColor) { Opacity = solidBrush.Opacity };
}
else if (originalColor.A > 0 && originalColor != Colors.Transparent &&
originalColor.R < 50 && originalColor.G < 50 && originalColor.B < 50) // 深色
{
return new SolidColorBrush(newColor) { Opacity = solidBrush.Opacity };
}
// 保持其他颜色不变(如透明色)
return new SolidColorBrush(originalColor) { Opacity = solidBrush.Opacity };
}
return source?.Clone();
}
///
/// 克隆 Pen 并更新颜色
///
private Pen ClonePen(Pen source, Color newColor)
{
var clonedBrush = CloneBrush(source.Brush, newColor);
return new Pen(clonedBrush, source.Thickness)
{
StartLineCap = source.StartLineCap,
EndLineCap = source.EndLineCap,
LineJoin = source.LineJoin,
MiterLimit = source.MiterLimit
};
}
///
/// 更新上下文菜单的主题(图标和文字颜色)
///
private void UpdateContextMenuTheme(ContextMenu contextMenu, bool isDarkTheme)
{
try
{
Color iconColor = isDarkTheme
? Color.FromRgb(243, 243, 243) // 深色主题使用浅色图标 #F3F3F3
: Color.FromRgb(34, 34, 34); // 浅色主题使用深色图标 #222222
foreach (var item in contextMenu.Items)
{
if (item is MenuItem menuItem)
{
// 更新文字颜色
menuItem.Foreground = ThemeHelper.GetTextPrimaryBrush();
// 更新图标颜色
if (menuItem.Icon is Image iconImage && iconImage.Source is DrawingImage drawingImage)
{
if (drawingImage.Drawing is DrawingGroup drawingGroup)
{
var clonedDrawing = CloneDrawingGroup(drawingGroup, iconColor);
iconImage.Source = new DrawingImage { Drawing = clonedDrawing };
}
}
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"更新上下文菜单主题时出错: {ex.Message}");
}
}
///
/// 更新按钮中的图标颜色
///
private void UpdateButtonIconColor(Border buttonBorder, bool isDarkTheme)
{
try
{
Color iconColor = isDarkTheme
? Color.FromRgb(243, 243, 243) // 深色主题使用浅色图标 #F3F3F3
: Color.FromRgb(34, 34, 34); // 浅色主题使用深色图标 #222222
// 查找按钮中的 Image 控件
var image = FindVisualChild(buttonBorder);
if (image != null && image.Source is DrawingImage drawingImage)
{
if (drawingImage.Drawing is DrawingGroup drawingGroup)
{
var clonedDrawing = CloneDrawingGroup(drawingGroup, iconColor);
image.Source = new DrawingImage { Drawing = clonedDrawing };
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"更新按钮图标颜色时出错: {ex.Message}");
}
}
///
/// 在视觉树中查找指定类型的子元素
///
private T FindVisualChild(DependencyObject parent) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is T result)
{
return result;
}
var childOfChild = FindVisualChild(child);
if (childOfChild != null)
{
return childOfChild;
}
}
return null;
}
///
/// 检查系统主题是否为浅色
///
private bool IsSystemThemeLight()
{
try
{
var registryKey = Microsoft.Win32.Registry.CurrentUser;
var themeKey = registryKey.OpenSubKey("software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize");
var keyValue = 0;
if (themeKey != null) keyValue = (int)themeKey.GetValue("SystemUsesLightTheme");
return keyValue == 1;
}
catch
{
return true; // 默认返回浅色主题
}
}
///
/// 预加载并初始化所有设置面板:对每个面板尝试加载设置、启用触摸支持并应用当前主题。
///
///
/// 该操作在 UI 线程上以 DispatcherPriority.Loaded 异步调度执行,并在完成后再次触发对所有面板的主题应用以确保视觉状态一致。
/// 对单个面板的初始化错误会被捕获并处理,不会中断其它面板的预加载流程。
///
private void LoadAllPanelsSettings()
{
try
{
// 预加载所有面板,确保它们在显示前都已初始化
// 使用 Dispatcher.BeginInvoke 延迟执行,确保所有面板都已创建
Dispatcher.BeginInvoke(new Action(() =>
{
try
{
// 所有设置面板列表
var allPanels = new UserControl[]
{
StartupPanel,
CanvasAndInkPanel,
GesturesPanel,
InkRecognitionPanel,
ThemePanel,
ShortcutsPanel,
CrashActionPanel,
PowerPointPanel,
AutomationPanel,
LuckyRandomPanel,
AdvancedPanel,
SnapshotPanel,
SecurityPanel,
UpdateCenterPanel,
SettingsAboutPanel,
AppearancePanel
};
// 预加载所有面板:调用 LoadSettings、EnableTouchSupport 和 ApplyTheme
foreach (var panel in allPanels)
{
if (panel != null)
{
try
{
// 直接调用 LoadSettings 确保设置被加载
var loadSettingsMethod = panel.GetType().GetMethod("LoadSettings",
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (loadSettingsMethod != null)
{
loadSettingsMethod.Invoke(panel, null);
}
// 调用 EnableTouchSupport 确保触摸支持已启用
var enableTouchSupportMethod = panel.GetType().GetMethod("EnableTouchSupport",
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (enableTouchSupportMethod != null)
{
enableTouchSupportMethod.Invoke(panel, null);
}
else
{
// 如果面板没有 EnableTouchSupport 方法,直接使用 MainWindowSettingsHelper
MainWindowSettingsHelper.EnableTouchSupportForControls(panel);
}
// 调用 ApplyTheme 确保主题已应用
var applyThemeMethod = panel.GetType().GetMethod("ApplyTheme",
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (applyThemeMethod != null)
{
applyThemeMethod.Invoke(panel, null);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"预加载面板 {panel?.GetType().Name} 时出错: {ex.Message}");
}
}
}
// 再次应用主题到所有面板,确保主题完全加载
Dispatcher.BeginInvoke(new Action(() =>
{
ApplyThemeToAllPanels();
}), System.Windows.Threading.DispatcherPriority.Loaded);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"预加载所有面板时出错: {ex.Message}");
}
}), System.Windows.Threading.DispatcherPriority.Loaded);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"加载设置面板设置时出错: {ex.Message}");
}
}
public enum SidebarItemType
{
Item,
Separator
}
public class SidebarItem : System.ComponentModel.INotifyPropertyChanged
{
public SidebarItemType Type { get; set; }
public string Title { get; set; }
public string Name { get; set; }
public ImageSource IconSource { get; set; }
private bool _selected = false;
private bool _isDarkTheme = false;
public bool Selected
{
get => _selected;
set
{
_selected = value;
OnPropertyChanged(nameof(_siBackground));
}
}
public bool IsDarkTheme
{
get => _isDarkTheme;
set
{
_isDarkTheme = value;
OnPropertyChanged(nameof(_siForeground));
OnPropertyChanged(nameof(_siBackground));
OnPropertyChanged(nameof(_spStroke));
}
}
public Visibility _spVisibility
{
get => Type == SidebarItemType.Separator ? Visibility.Visible : Visibility.Collapsed;
}
public Visibility _siVisibility
{
get => Type == SidebarItemType.Item ? Visibility.Visible : Visibility.Collapsed;
}
public SolidColorBrush _siBackground
{
get
{
if (Selected)
{
return _isDarkTheme
? ThemeHelper.GetSelectedBackgroundBrush() // Windows 系统选中背景 #3E3E3E
: new SolidColorBrush(Color.FromRgb(237, 237, 237));
}
return new SolidColorBrush(Colors.Transparent);
}
}
public SolidColorBrush _siForeground
{
get => _isDarkTheme
? ThemeHelper.GetTextPrimaryBrush() // Windows 系统主文字颜色 #F3F3F3
: new SolidColorBrush(Color.FromRgb(0, 0, 0));
}
public SolidColorBrush _spStroke
{
get => _isDarkTheme
? ThemeHelper.GetSeparatorBrush() // Windows 系统分隔线 #3E3E3E
: new SolidColorBrush(Color.FromRgb(237, 237, 237));
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
public string _selectedSidebarItemName = "";
public ObservableCollection SidebarItems = new ObservableCollection();
///
/// 面板配置类,统一管理面板的配置信息
///
public class PanelConfiguration
{
public string Title { get; set; }
public string Name { get; set; }
public string IconResourceKey { get; set; }
public Grid Panel { get; set; }
public ScrollViewer ScrollViewer { get; set; }
public UserControl UserControl { get; set; }
}
///
/// 面板配置列表
///
private List _panelConfigurations;
///
/// 初始化侧边栏项
///
private void InitializeSidebarItems()
{
// 初始化面板配置
_panelConfigurations = new List
{
new PanelConfiguration
{
Title = "启动时行为",
Name = "StartupItem",
IconResourceKey = "StartupIcon",
Panel = StartupPane,
ScrollViewer = StartupPanel.ScrollViewerEx,
UserControl = StartupPanel
},
new PanelConfiguration
{
Title = "画板和墨迹",
Name = "CanvasAndInkItem",
IconResourceKey = "CanvasAndInkIcon",
Panel = CanvasAndInkPane,
ScrollViewer = CanvasAndInkPanel.ScrollViewerEx,
UserControl = CanvasAndInkPanel
},
new PanelConfiguration
{
Title = "手势操作",
Name = "GesturesItem",
IconResourceKey = "GesturesIcon",
Panel = GesturesPane,
ScrollViewer = GesturesPanel.ScrollViewerEx,
UserControl = GesturesPanel
},
new PanelConfiguration
{
Title = "墨迹纠正",
Name = "InkRecognitionItem",
IconResourceKey = "InkRecognitionIcon",
Panel = InkRecognitionPane,
ScrollViewer = InkRecognitionPanel.ScrollViewerEx,
UserControl = InkRecognitionPanel
},
new PanelConfiguration
{
Title = "个性化设置",
Name = "ThemeItem",
IconResourceKey = "AppearanceIcon",
Panel = ThemePane,
ScrollViewer = ThemePanel.ScrollViewerEx,
UserControl = ThemePanel
},
new PanelConfiguration
{
Title = "快捷键设置",
Name = "ShortcutsItem",
IconResourceKey = "ShortcutsIcon",
Panel = ShortcutsPane,
ScrollViewer = ShortcutsPanel.ScrollViewerEx,
UserControl = ShortcutsPanel
},
new PanelConfiguration
{
Title = "崩溃处理",
Name = "CrashActionItem",
IconResourceKey = "CrashActionIcon",
Panel = CrashActionPane,
ScrollViewer = CrashActionPanel.ScrollViewerEx,
UserControl = CrashActionPanel
},
new PanelConfiguration
{
Title = "PowerPoint 支持",
Name = "PowerPointItem",
IconResourceKey = "PowerPointIcon",
Panel = PowerPointPane,
ScrollViewer = PowerPointPanel.ScrollViewerEx,
UserControl = PowerPointPanel
},
new PanelConfiguration
{
Title = "自动化行为",
Name = "AutomationItem",
IconResourceKey = "AutomationIcon",
Panel = AutomationPane,
ScrollViewer = AutomationPanel.ScrollViewerEx,
UserControl = AutomationPanel
},
new PanelConfiguration
{
Title = "随机点名",
Name = "LuckyRandomItem",
IconResourceKey = "LuckyRandomIcon",
Panel = LuckyRandomPane,
ScrollViewer = LuckyRandomPanel.ScrollViewerEx,
UserControl = LuckyRandomPanel
},
new PanelConfiguration
{
Title = "高级选项",
Name = "AdvancedItem",
IconResourceKey = "AdvancedIcon",
Panel = AdvancedPane,
ScrollViewer = AdvancedPanel.ScrollViewerEx,
UserControl = AdvancedPanel
},
new PanelConfiguration
{
Title = "截图和屏幕捕捉",
Name = "SnapshotItem",
IconResourceKey = "SnapshotIcon",
Panel = SnapshotPane,
ScrollViewer = SnapshotPanel.ScrollViewerEx,
UserControl = SnapshotPanel
},
new PanelConfiguration
{
Title = "安全",
Name = "SecurityItem",
IconResourceKey = "SecurityIcon",
Panel = SecurityPane,
ScrollViewer = SecurityPanel.ScrollViewerEx,
UserControl = SecurityPanel
},
new PanelConfiguration
{
Title = "更新中心",
Name = "UpdateCenterItem",
IconResourceKey = "UpdateCenterIcon",
Panel = UpdateCenterPane,
ScrollViewer = UpdateCenterPanel.UpdateCenterScrollViewerEx,
UserControl = UpdateCenterPanel
},
new PanelConfiguration
{
Title = "关于 InkCanvasForClass",
Name = "AboutItem",
IconResourceKey = "AboutIcon",
Panel = AboutPane,
ScrollViewer = SettingsAboutPanel.AboutScrollViewerEx,
UserControl = SettingsAboutPanel
}
};
SidebarItemsControl.ItemsSource = SidebarItems;
// 创建侧边栏项
foreach (var config in _panelConfigurations)
{
SidebarItems.Add(new SidebarItem
{
Type = SidebarItemType.Item,
Title = config.Title,
Name = config.Name,
IconSource = FindResource(config.IconResourceKey) as DrawingImage,
Selected = false
});
}
// 添加分隔符
AddSidebarSeparator(4); // 在第 4 个项后添加
AddSidebarSeparator(7); // 在第 7 个项后添加
AddSidebarSeparator(11); // 在第 11 个项后添加
AddSidebarSeparator(14); // 在第 14 个项后添加
AddSidebarSeparator(16); // 在第 16 个项后添加
}
///
/// 在指定位置添加侧边栏分隔符
///
/// 添加位置
private void AddSidebarSeparator(int index)
{
if (index >= 0 && index <= SidebarItems.Count)
{
SidebarItems.Insert(index, new SidebarItem
{
Type = SidebarItemType.Separator
});
}
}
///
/// 订阅面板事件
///
private void SubscribePanelEvents()
{
// 订阅所有面板的滚动和阴影事件
foreach (var config in _panelConfigurations)
{
if (config.UserControl != null)
{
// 检查 UserControl 是否有这些事件
var type = config.UserControl.GetType();
var shadowEvent = type.GetEvent("IsTopBarNeedShadowEffect");
var noShadowEvent = type.GetEvent("IsTopBarNeedNoShadowEffect");
if (shadowEvent != null)
{
// 创建与事件类型匹配的委托
var eventHandlerType = shadowEvent.EventHandlerType;
var handlerMethod = GetType().GetMethod("HandleShadowEffect",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (handlerMethod != null)
{
var handler = System.Delegate.CreateDelegate(eventHandlerType, this, handlerMethod);
shadowEvent.AddEventHandler(config.UserControl, handler);
}
}
if (noShadowEvent != null)
{
// 创建与事件类型匹配的委托
var eventHandlerType = noShadowEvent.EventHandlerType;
var handlerMethod = GetType().GetMethod("HandleNoShadowEffect",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (handlerMethod != null)
{
var handler = System.Delegate.CreateDelegate(eventHandlerType, this, handlerMethod);
noShadowEvent.AddEventHandler(config.UserControl, handler);
}
}
}
}
// 订阅主题变化事件
if (ThemePanel != null)
{
ThemePanel.ThemeChanged += (o, s) =>
{
ApplyTheme();
ApplyThemeToAllPanels();
};
}
}
///
/// 处理阴影效果事件
///
private void HandleShadowEffect(object sender, EventArgs e)
{
DropShadowEffectTopBar.Opacity = 0.25;
}
///
/// 处理无阴影效果事件
///
private void HandleNoShadowEffect(object sender, EventArgs e)
{
DropShadowEffectTopBar.Opacity = 0;
}
///
/// 初始化搜索面板事件
///
private void InitializeSearchPanelEvents()
{
SearchPanelControl.NavigateToItem += SearchPanel_NavigateToItem;
SearchPanelControl.CloseSearch += SearchPanel_CloseSearch;
}
///
/// 初始化菜单事件
///
private void InitializeMenuEvents()
{
// 订阅菜单关闭事件,确保状态同步
if (MenuButtonContextMenu != null)
{
MenuButtonContextMenu.Closed += (s, e) =>
{
// 菜单关闭时的处理
};
}
}
///
/// 初始化主题状态
///
private void InitializeThemeState()
{
// 初始化侧边栏项目的主题状态
bool isDarkTheme = MainWindow.Settings?.Appearance != null &&
(MainWindow.Settings.Appearance.Theme == 1 ||
(MainWindow.Settings.Appearance.Theme == 2 && !IsSystemThemeLight()));
foreach (var item in SidebarItems)
{
item.IsDarkTheme = isDarkTheme;
}
UpdateSidebarItemsSelection();
}
///
/// 根据当前选中的侧边栏项更新侧边栏条目状态、面板可见性与主题并将视图滚动到顶部。
///
///
/// - 将 SidebarItems 中的 Selected 与 SettingsWindowTitle.Text 与字段 _selectedSidebarItemName 同步;
/// - 根据应用设置计算并同步每个 SidebarItem 的 IsDarkTheme;
/// - 切换各个面板(Pane)的 Visibility,仅显示与 _selectedSidebarItemName 对应的面板;
/// - 异步调用所选面板(若存在)的 ApplyTheme 方法以确保新显示面板使用正确主题;
/// - 将所有已注册的 SettingsPaneScrollViewers 滚动到顶部以重置视图位置。
///
public void UpdateSidebarItemsSelection()
{
// 更新侧边栏项的选中状态
foreach (var si in SidebarItems)
{
si.Selected = si.Name == _selectedSidebarItemName;
}
CollectionViewSource.GetDefaultView(SidebarItems).Refresh();
// 确保主题状态同步
bool isDarkTheme = MainWindow.Settings?.Appearance != null &&
(MainWindow.Settings.Appearance.Theme == 1 ||
(MainWindow.Settings.Appearance.Theme == 2 && !IsSystemThemeLight()));
foreach (var si in SidebarItems)
{
si.IsDarkTheme = isDarkTheme;
}
// 切换面板可见性并获取选中的面板
UserControl selectedPanel = null;
if (_panelConfigurations != null)
{
foreach (var config in _panelConfigurations)
{
// 更新窗口标题
if (config.Name == _selectedSidebarItemName && SettingsWindowTitle != null)
{
SettingsWindowTitle.Text = config.Title;
selectedPanel = config.UserControl;
}
// 切换面板可见性
if (config.Panel != null)
{
config.Panel.Visibility = config.Name == _selectedSidebarItemName
? Visibility.Visible
: Visibility.Collapsed;
}
// 滚动到顶部
if (config.ScrollViewer != null)
{
config.ScrollViewer.ScrollToTop();
}
}
}
// 为新显示的面板应用主题(延迟执行,确保面板已完全显示)
if (selectedPanel != null)
{
Dispatcher.BeginInvoke(new Action(() =>
{
try
{
var applyThemeMethod = selectedPanel.GetType().GetMethod("ApplyTheme",
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (applyThemeMethod != null)
{
applyThemeMethod.Invoke(selectedPanel, null);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"切换面板时应用主题到 {selectedPanel.GetType().Name} 时出错: {ex.Message}");
}
}), System.Windows.Threading.DispatcherPriority.Loaded);
}
}
private void ScrollBar_Scroll(object sender, RoutedEventArgs e)
{
var scrollbar = (ScrollBar)sender;
var scrollviewer = scrollbar.FindAscendant();
if (scrollviewer != null) scrollviewer.ScrollToVerticalOffset(scrollbar.Track.Value);
}
private void ScrollBarTrack_MouseEnter(object sender, MouseEventArgs e)
{
var border = (Border)sender;
if (border.Child is Track track)
{
track.Width = 16;
track.Margin = new Thickness(0, 0, -2, 0);
var scrollbar = track.FindAscendant();
if (scrollbar != null) scrollbar.Width = 16;
var grid = track.FindAscendant();
if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder)
{
backgroundBorder.Width = 8;
backgroundBorder.CornerRadius = new CornerRadius(4);
backgroundBorder.Opacity = 1;
}
var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb);
if (thumb != null)
{
var _thumb = thumb as Border;
_thumb.CornerRadius = new CornerRadius(4);
_thumb.Width = 8;
_thumb.Margin = new Thickness(-0.75, 0, 1, 0);
_thumb.Background = new SolidColorBrush(Color.FromRgb(138, 138, 138));
}
}
}
private void ScrollBarTrack_MouseLeave(object sender, MouseEventArgs e)
{
var border = (Border)sender;
border.Background = new SolidColorBrush(Colors.Transparent);
border.CornerRadius = new CornerRadius(0);
if (border.Child is Track track)
{
track.Width = 6;
track.Margin = new Thickness(0, 0, 0, 0);
var scrollbar = track.FindAscendant();
if (scrollbar != null) scrollbar.Width = 6;
var grid = track.FindAscendant();
if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder)
{
backgroundBorder.Width = 3;
backgroundBorder.CornerRadius = new CornerRadius(1.5);
backgroundBorder.Opacity = 0;
}
var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb);
if (thumb != null)
{
var _thumb = thumb as Border;
_thumb.CornerRadius = new CornerRadius(1.5);
_thumb.Width = 3;
_thumb.Margin = new Thickness(0);
_thumb.Background = new SolidColorBrush(Color.FromRgb(195, 195, 195));
}
}
}
private void ScrollbarThumb_MouseDown(object sender, MouseButtonEventArgs e)
{
var thumb = (Thumb)sender;
var border = thumb.Template.FindName("ScrollbarThumbEx", thumb);
((Border)border).Background = new SolidColorBrush(Color.FromRgb(95, 95, 95));
}
private void ScrollbarThumb_MouseUp(object sender, MouseButtonEventArgs e)
{
var thumb = (Thumb)sender;
var border = thumb.Template.FindName("ScrollbarThumbEx", thumb);
((Border)border).Background = new SolidColorBrush(Color.FromRgb(138, 138, 138));
}
private Border _sidebarItemMouseDownBorder = null;
private void SidebarItem_MouseDown(object sender, MouseButtonEventArgs e)
{
if (_sidebarItemMouseDownBorder != null || _sidebarItemMouseDownBorder == sender) return;
_sidebarItemMouseDownBorder = (Border)sender;
var bd = sender as Border;
if (bd.FindDescendantByName("MouseFeedbackBorder") is Border feedbackBd) feedbackBd.Opacity = 0.12;
}
private void SidebarItem_MouseUp(object sender, MouseButtonEventArgs e)
{
if (_sidebarItemMouseDownBorder == null || _sidebarItemMouseDownBorder != sender) return;
if (_sidebarItemMouseDownBorder.Tag is SidebarItem data) _selectedSidebarItemName = data.Name;
SidebarItem_MouseLeave(sender, null);
UpdateSidebarItemsSelection();
}
private void SidebarItem_MouseLeave(object sender, MouseEventArgs e)
{
if (_sidebarItemMouseDownBorder == null || _sidebarItemMouseDownBorder != sender) return;
if (_sidebarItemMouseDownBorder.FindDescendantByName("MouseFeedbackBorder") is Border feedbackBd) feedbackBd.Opacity = 0;
_sidebarItemMouseDownBorder = null;
}
private void TopBarBorder_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton != MouseButton.Left) return;
DragMove();
}
private void SidebarTopBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton != MouseButton.Left) return;
var source = e.OriginalSource as DependencyObject;
if (IsInsideElement(source, SearchButtonBorder) || IsInsideElement(source, MenuButtonBorder))
return;
DragMove();
}
private static bool IsInsideElement(DependencyObject source, DependencyObject target)
{
if (source == null || target == null) return false;
if (source == target) return true;
return IsInsideElement(VisualTreeHelper.GetParent(source), target);
}
private void CloseButton_Click(object sender, MouseButtonEventArgs e)
{
Close();
}
private void SearchButton_Click(object sender, MouseButtonEventArgs e)
{
// 显示搜索界面
SearchPane.Visibility = Visibility.Visible;
SearchPanelControl.FocusSearchBox();
}
private void SearchPanel_NavigateToItem(object sender, string itemName)
{
// 隐藏搜索界面
SearchPane.Visibility = Visibility.Collapsed;
// 导航到对应的设置项
NavigateToSidebarItem(itemName);
}
private void SearchPanel_CloseSearch(object sender, EventArgs e)
{
// 隐藏搜索界面
SearchPane.Visibility = Visibility.Collapsed;
}
private void NavigateToSidebarItem(string itemName)
{
// 查找对应的侧边栏项并选中
foreach (var item in SidebarItems)
{
if (item.Name == itemName)
{
SelectSidebarItem(item);
break;
}
}
}
private void SelectSidebarItem(SidebarItem item)
{
_selectedSidebarItemName = item.Name;
UpdateSidebarItemsSelection();
}
private void MenuButton_Click(object sender, MouseButtonEventArgs e)
{
// 切换上下文菜单的显示状态
if (MenuButtonContextMenu != null)
{
MenuButtonContextMenu.PlacementTarget = MenuButtonBorder;
MenuButtonContextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
// 如果菜单已打开,则关闭;如果已关闭,则打开
bool isCurrentlyOpen = MenuButtonContextMenu.IsOpen;
if (isCurrentlyOpen)
{
// 如果菜单已打开,直接关闭
MenuButtonContextMenu.IsOpen = false;
}
else
{
// 如果菜单未打开,打开菜单
MenuButtonContextMenu.IsOpen = true;
}
// 标记事件已处理,防止菜单拦截点击
e.Handled = true;
}
}
private void MenuItemExit_Click(object sender, RoutedEventArgs e)
{
// 关闭设置窗口
Close();
// 调用主窗口的退出方法
if (_mainWindow != null)
{
_mainWindow.BtnExit_Click(sender, e);
}
}
private void MenuItemRestart_Click(object sender, RoutedEventArgs e)
{
// 关闭设置窗口
Close();
// 调用主窗口的重启方法
if (_mainWindow != null)
{
_mainWindow.BtnRestart_Click(sender, e);
}
}
private void MenuItemReset_Click(object sender, RoutedEventArgs e)
{
// 调用主窗口的重置配置方法
if (_mainWindow != null)
{
_mainWindow.BtnResetToSuggestion_Click(sender, e);
}
}
private void MenuItemSwitchToOldSettings_Click(object sender, RoutedEventArgs e)
{
// 关闭新设置窗口
Close();
}
private void ToggleSwitch_Click(object sender, MouseButtonEventArgs e)
{
var border = sender as Border;
if (border != null)
{
// 切换开关状态
bool isOn = border.Background.ToString() == "#FF3584E4";
border.Background = isOn ? new SolidColorBrush(Color.FromRgb(225, 225, 225)) : new SolidColorBrush(Color.FromRgb(53, 132, 228));
// 切换内部圆点的位置
var innerBorder = border.Child as Border;
if (innerBorder != null)
{
innerBorder.HorizontalAlignment = isOn ? HorizontalAlignment.Left : HorizontalAlignment.Right;
}
// 根据Tag处理不同的设置项
string tag = border.Tag?.ToString();
if (!string.IsNullOrEmpty(tag))
{
HandleSettingChange(tag, !isOn);
}
}
}
private void HandleSettingChange(string settingName, bool value)
{
// 根据设置名称处理不同的设置项
switch (settingName)
{
case "UseObviousCursor":
// 处理使用更加明显的画笔光标设置
break;
case "HideInkWhenExitAnnotationMode":
// 处理退出批注模式后隐藏墨迹设置
break;
case "DisablePenPressure":
// 处理禁用模拟笔锋设置
break;
case "ClearInkWithoutHistory":
// 处理清空墨迹时不保留时光机历史记录设置
break;
case "UseBlackBackgroundForTransparency":
// 处理AllowTransparency使用黑色背景设置
break;
case "KeepHyperbolaAsymptote":
// 处理保留双曲线渐近线设置
break;
case "UseInkEraser":
// 处理使用墨迹擦设置
break;
case "UseDefaultBackgroundColorForNewPage":
// 处理创建新页时始终使用默认背景色设置
break;
case "DebugMode":
// 处理调试模式设置
break;
case "PerformanceMonitoring":
// 处理性能监控设置
break;
case "AutoRestartOnCrash":
// 处理崩溃时自动重启设置
break;
case "SendCrashReport":
// 处理发送崩溃报告设置
break;
case "EnableLuckyRandom":
// 处理启用幸运随机功能设置
break;
case "EnableInkToShape":
// 处理启用墨迹转形状设置
break;
case "InkRecognitionRange":
// 处理墨迹识别范围设置
break;
case "RecognizeQuadrilateral":
// 处理识别四边形设置
break;
case "RecognizeTriangle":
// 处理识别三角形设置
break;
case "RecognizeCircle":
// 处理识别圆形设置
break;
case "RecognizeLine":
// 处理识别直线设置
break;
case "EnablePressureSimulation":
// 处理启用三角形和矩形每边模拟压力值设置
break;
case "ConcentricCircleCorrection":
// 处理同心圆识别矫正设置
break;
case "EnableAutoHide":
// 处理启用自动收纳设置
break;
case "EnableAutoKill":
// 处理启用自动查杀设置
break;
case "EnableWhiteboardKiller":
// 处理启用桌面画板悬浮窗杀手设置
break;
case "EnablePowerPointCom":
// 处理启用 PowerPoint COM 支持设置
break;
case "EnableWpsCom":
// 处理启用 WPS COM 支持设置
break;
case "EnableVsto":
// 处理启用 VSTO 支持设置
break;
default:
// 未知设置项
break;
}
}
private void OptionButton_Click(object sender, MouseButtonEventArgs e)
{
var border = sender as Border;
if (border != null)
{
string tag = border.Tag?.ToString();
if (!string.IsNullOrEmpty(tag))
{
// 清除同组其他按钮的选中状态
ClearOtherOptionsInGroup(border, tag);
// 设置当前按钮为选中状态
border.Background = new SolidColorBrush(Color.FromRgb(225, 225, 225));
var textBlock = border.Child as TextBlock;
if (textBlock != null)
{
textBlock.FontWeight = FontWeights.Bold;
}
// 处理选项变化
HandleOptionChange(tag);
}
}
}
private void ClearOtherOptionsInGroup(Border currentBorder, string currentTag)
{
// 获取当前按钮所在的父容器
var parent = currentBorder.Parent as StackPanel;
if (parent != null)
{
// 获取组名(Tag中下划线前的部分)
string groupName = currentTag.Split('_')[0];
// 清除同组其他按钮的选中状态
foreach (var child in parent.Children)
{
if (child is Border border && border != currentBorder)
{
string childTag = border.Tag?.ToString();
if (!string.IsNullOrEmpty(childTag) && childTag.StartsWith(groupName + "_"))
{
border.Background = new SolidColorBrush(Colors.Transparent);
var textBlock = border.Child as TextBlock;
if (textBlock != null)
{
textBlock.FontWeight = FontWeights.Normal;
}
}
}
}
}
}
private void HandleOptionChange(string optionTag)
{
// 根据选项标签处理不同的选项变化
string[] parts = optionTag.Split('_');
if (parts.Length >= 2)
{
string group = parts[0];
string value = parts[1];
switch (group)
{
case "EraserSize":
// 处理板擦橡皮大小设置
break;
case "DefaultBackgroundColor":
// 处理默认背景色设置
break;
case "DefaultPaperFormat":
// 处理默认稿纸格式设置
break;
case "AutoSaveInterval":
// 处理自动保存间隔设置
break;
case "ScreenshotQuality":
// 处理截图质量设置
break;
case "ScreenshotFormat":
// 处理截图格式设置
break;
case "InkRecognitionBehavior":
// 处理墨迹识别后转换行为设置
break;
case "Theme":
// 处理主题设置
break;
case "Language":
// 处理语言设置
break;
default:
// 未知选项组
break;
}
}
}
#region 自定义滑块触摸支持
///
/// 为自定义滑块控件添加触摸和手写笔事件支持
///
private void AddTouchSupportToCustomSliders()
{
try
{
// 延迟执行,确保UI元素已加载
Dispatcher.BeginInvoke(new Action(() =>
{
// 查找所有自定义滑块控件并添加触摸支持
AddTouchSupportToCustomSliderInPane(CanvasAndInkPane);
AddTouchSupportToCustomSliderInPane(ThemePane);
AddTouchSupportToCustomSliderInPane(PowerPointPane);
AddTouchSupportToCustomSliderInPane(AutomationPane);
AddTouchSupportToCustomSliderInPane(LuckyRandomPane);
AddTouchSupportToCustomSliderInPane(AdvancedPane);
}), System.Windows.Threading.DispatcherPriority.Loaded);
}
catch (Exception ex)
{
// 记录错误但不影响程序运行
Debug.WriteLine($"添加自定义滑块触摸支持时出错: {ex.Message}");
}
}
///
/// 为指定面板中的自定义滑块控件添加触摸支持
///
/// 面板控件
private void AddTouchSupportToCustomSliderInPane(Grid pane)
{
if (pane == null) return;
// 查找面板中的所有自定义滑块控件
var customSliders = FindCustomSlidersInPanel(pane);
foreach (var slider in customSliders)
{
AddTouchSupportToCustomSlider(slider);
}
}
///
/// 在面板中查找自定义滑块控件
///
/// 面板控件
/// 自定义滑块控件列表
private List FindCustomSlidersInPanel(DependencyObject panel)
{
var customSliders = new List();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(panel); i++)
{
var child = VisualTreeHelper.GetChild(panel, i);
// 检查是否是自定义滑块控件(包含GnomeSliderThumb图片的Grid)
if (child is Grid grid)
{
var customSlider = FindCustomSliderInGrid(grid);
if (customSlider != null)
{
customSliders.Add(customSlider);
}
}
// 递归查找子元素
customSliders.AddRange(FindCustomSlidersInPanel(child));
}
return customSliders;
}
///
/// 在Grid中查找自定义滑块控件
///
/// Grid控件
/// 自定义滑块信息
private CustomSliderInfo FindCustomSliderInGrid(Grid grid)
{
// 查找包含GnomeSliderThumb图片的Grid
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(grid); i++)
{
var child = VisualTreeHelper.GetChild(grid, i);
if (child is Image image && image.Source != null)
{
var sourceName = image.Source.ToString();
if (sourceName.Contains("GnomeSliderThumb"))
{
// 找到滑块控件,创建自定义滑块信息
var customSlider = new CustomSliderInfo
{
Container = grid,
ThumbImage = image,
TrackBorder = FindTrackBorderInGrid(grid),
ValueBorder = FindValueBorderInGrid(grid)
};
return customSlider;
}
}
}
return null;
}
///
/// 在Grid中查找轨道Border
///
/// Grid控件
/// 轨道Border
private Border FindTrackBorderInGrid(Grid grid)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(grid); i++)
{
var child = VisualTreeHelper.GetChild(grid, i);
if (child is Border border && border.Background != null)
{
var brush = border.Background as SolidColorBrush;
if (brush != null && brush.Color.ToString() == "#FFDEDEDE")
{
return border;
}
}
}
return null;
}
///
/// 在Grid中查找值显示Border
///
/// Grid控件
/// 值显示Border
private Border FindValueBorderInGrid(Grid grid)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(grid); i++)
{
var child = VisualTreeHelper.GetChild(grid, i);
if (child is Border border && border.Background != null)
{
var brush = border.Background as SolidColorBrush;
if (brush != null && brush.Color.ToString() == "#FF3584E4")
{
return border;
}
}
}
return null;
}
///
/// 为自定义滑块控件添加触摸支持
///
/// 自定义滑块信息
private void AddTouchSupportToCustomSlider(CustomSliderInfo customSlider)
{
if (customSlider?.Container == null) return;
// 启用触摸和手写笔支持
customSlider.Container.IsManipulationEnabled = true;
// 添加触摸事件
customSlider.Container.TouchDown += (s, e) => CustomSlider_TouchDown(s, e, customSlider);
customSlider.Container.TouchMove += (s, e) => CustomSlider_TouchMove(s, e, customSlider);
customSlider.Container.TouchUp += (s, e) => CustomSlider_TouchUp(s, e, customSlider);
// 添加手写笔事件
customSlider.Container.StylusDown += (s, e) => CustomSlider_StylusDown(s, e, customSlider);
customSlider.Container.StylusMove += (s, e) => CustomSlider_StylusMove(s, e, customSlider);
customSlider.Container.StylusUp += (s, e) => CustomSlider_StylusUp(s, e, customSlider);
// 添加操作事件
customSlider.Container.ManipulationStarted += (s, e) => CustomSlider_ManipulationStarted(s, e, customSlider);
customSlider.Container.ManipulationDelta += (s, e) => CustomSlider_ManipulationDelta(s, e, customSlider);
customSlider.Container.ManipulationCompleted += (s, e) => CustomSlider_ManipulationCompleted(s, e, customSlider);
}
///
/// 自定义滑块触摸按下事件处理
///
private void CustomSlider_TouchDown(object sender, TouchEventArgs e, CustomSliderInfo customSlider)
{
customSlider.Container.CaptureTouch(e.TouchDevice);
customSlider.IsTouchCaptured = true;
var touchPoint = e.GetTouchPoint(customSlider.Container);
UpdateCustomSliderValueFromPosition(customSlider, touchPoint.Position);
e.Handled = true;
}
///
/// 自定义滑块触摸移动事件处理
///
private void CustomSlider_TouchMove(object sender, TouchEventArgs e, CustomSliderInfo customSlider)
{
// 检查是否有触摸捕获
if (!customSlider.IsTouchCaptured) return;
var touchPoint = e.GetTouchPoint(customSlider.Container);
UpdateCustomSliderValueFromPosition(customSlider, touchPoint.Position);
e.Handled = true;
}
///
/// 自定义滑块触摸释放事件处理
///
private void CustomSlider_TouchUp(object sender, TouchEventArgs e, CustomSliderInfo customSlider)
{
customSlider.Container.ReleaseTouchCapture(e.TouchDevice);
customSlider.IsTouchCaptured = false;
e.Handled = true;
}
///
/// 自定义滑块手写笔按下事件处理
///
private void CustomSlider_StylusDown(object sender, StylusDownEventArgs e, CustomSliderInfo customSlider)
{
customSlider.Container.CaptureStylus();
var stylusPoint = e.GetStylusPoints(customSlider.Container);
if (stylusPoint.Count > 0)
{
UpdateCustomSliderValueFromPosition(customSlider, stylusPoint[0].ToPoint());
}
e.Handled = true;
}
///
/// 自定义滑块手写笔移动事件处理
///
private void CustomSlider_StylusMove(object sender, StylusEventArgs e, CustomSliderInfo customSlider)
{
if (!customSlider.Container.IsStylusCaptured) return;
var stylusPoint = e.GetStylusPoints(customSlider.Container);
if (stylusPoint.Count > 0)
{
UpdateCustomSliderValueFromPosition(customSlider, stylusPoint[0].ToPoint());
}
e.Handled = true;
}
///
/// 自定义滑块手写笔释放事件处理
///
private void CustomSlider_StylusUp(object sender, StylusEventArgs e, CustomSliderInfo customSlider)
{
customSlider.Container.ReleaseStylusCapture();
e.Handled = true;
}
///
/// 自定义滑块操作开始事件处理
///
private void CustomSlider_ManipulationStarted(object sender, ManipulationStartedEventArgs e, CustomSliderInfo customSlider)
{
e.Handled = true;
}
///
/// 自定义滑块操作变化事件处理
///
private void CustomSlider_ManipulationDelta(object sender, ManipulationDeltaEventArgs e, CustomSliderInfo customSlider)
{
var manipulationOrigin = e.ManipulationOrigin;
UpdateCustomSliderValueFromPosition(customSlider, manipulationOrigin);
e.Handled = true;
}
///
/// 自定义滑块操作完成事件处理
///
private void CustomSlider_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e, CustomSliderInfo customSlider)
{
e.Handled = true;
}
///
/// 根据触摸/手写笔位置更新自定义滑块值
///
/// 自定义滑块信息
/// 触摸/手写笔位置
private void UpdateCustomSliderValueFromPosition(CustomSliderInfo customSlider, Point position)
{
if (customSlider?.TrackBorder == null || customSlider.ThumbImage == null) return;
try
{
// 计算滑块轨道的实际位置和长度
var trackWidth = customSlider.TrackBorder.ActualWidth;
if (trackWidth <= 0) return;
// 考虑拇指大小,计算有效轨道长度
var thumbSize = 21; // 根据XAML中的Width="21"
var effectiveWidth = trackWidth - thumbSize;
// 计算相对位置(0-1之间),考虑拇指大小
var adjustedX = position.X - thumbSize / 2;
var relativePosition = Math.Max(0, Math.Min(1, adjustedX / effectiveWidth));
// 更新滑块位置
var thumbTransform = customSlider.ThumbImage.RenderTransform as TranslateTransform;
if (thumbTransform == null)
{
thumbTransform = new TranslateTransform();
customSlider.ThumbImage.RenderTransform = thumbTransform;
}
// 计算新的滑块位置
var newX = relativePosition * effectiveWidth;
thumbTransform.X = newX;
// 更新值显示Border的宽度
if (customSlider.ValueBorder != null)
{
var valueWidth = relativePosition * trackWidth;
customSlider.ValueBorder.Width = Math.Max(0, valueWidth);
// 调整值显示Border的位置
var valueMargin = customSlider.ValueBorder.Margin;
customSlider.ValueBorder.Margin = new Thickness(0, valueMargin.Top, trackWidth - valueWidth, valueMargin.Bottom);
}
// 这里可以根据需要添加值变化事件处理
// 例如:OnCustomSliderValueChanged(customSlider, relativePosition);
}
catch (Exception ex)
{
Debug.WriteLine($"更新自定义滑块值时出错: {ex.Message}");
}
}
///
/// 自定义滑块信息类
///
private class CustomSliderInfo
{
public Grid Container { get; set; }
public Image ThumbImage { get; set; }
public Border TrackBorder { get; set; }
public Border ValueBorder { get; set; }
public bool IsTouchCaptured { get; set; } = false;
}
#endregion
}
}