improve:issue #112

This commit is contained in:
2025-08-23 21:39:00 +08:00
parent 108c6b2b17
commit 710a9014dd
13 changed files with 1414 additions and 19 deletions
+301
View File
@@ -0,0 +1,301 @@
using System;
using System.Collections.Generic;
using System.Windows.Input;
using NHotkey.Wpf;
namespace Ink_Canvas.Helpers
{
/// <summary>
/// 全局快捷键管理器 - 使用NHotkey库实现全局快捷键功能
/// </summary>
public class GlobalHotkeyManager : IDisposable
{
#region Private Fields
private readonly Dictionary<string, HotkeyInfo> _registeredHotkeys;
private readonly MainWindow _mainWindow;
private bool _isDisposed = false;
#endregion
#region Constructor
public GlobalHotkeyManager(MainWindow mainWindow)
{
_mainWindow = mainWindow ?? throw new ArgumentNullException(nameof(mainWindow));
_registeredHotkeys = new Dictionary<string, HotkeyInfo>();
}
#endregion
#region Public Methods
/// <summary>
/// 注册全局快捷键
/// </summary>
/// <param name="hotkeyName">快捷键名称</param>
/// <param name="key">按键</param>
/// <param name="modifiers">修饰键</param>
/// <param name="action">执行动作</param>
/// <returns>是否注册成功</returns>
public bool RegisterHotkey(string hotkeyName, Key key, ModifierKeys modifiers, Action action)
{
try
{
if (_isDisposed)
return false;
// 如果快捷键已存在,先注销
if (_registeredHotkeys.ContainsKey(hotkeyName))
{
UnregisterHotkey(hotkeyName);
}
// 创建快捷键信息
var hotkeyInfo = new HotkeyInfo
{
Name = hotkeyName,
Key = key,
Modifiers = modifiers,
Action = action
};
// 注册快捷键
HotkeyManager.Current.AddOrReplace(hotkeyName, key, modifiers, (sender, e) =>
{
try
{
// 确保在主线程中执行
_mainWindow.Dispatcher.Invoke(() =>
{
action?.Invoke();
});
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"执行快捷键 {hotkeyName} 时出错: {ex.Message}", LogHelper.LogType.Error);
}
});
_registeredHotkeys[hotkeyName] = hotkeyInfo;
LogHelper.WriteLogToFile($"成功注册全局快捷键: {hotkeyName} ({modifiers}+{key})", LogHelper.LogType.Event);
return true;
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"注册全局快捷键 {hotkeyName} 失败: {ex.Message}", LogHelper.LogType.Error);
return false;
}
}
/// <summary>
/// 注销指定快捷键
/// </summary>
/// <param name="hotkeyName">快捷键名称</param>
/// <returns>是否注销成功</returns>
public bool UnregisterHotkey(string hotkeyName)
{
try
{
if (_isDisposed || !_registeredHotkeys.ContainsKey(hotkeyName))
return false;
HotkeyManager.Current.Remove(hotkeyName);
_registeredHotkeys.Remove(hotkeyName);
LogHelper.WriteLogToFile($"成功注销全局快捷键: {hotkeyName}", LogHelper.LogType.Event);
return true;
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"注销全局快捷键 {hotkeyName} 失败: {ex.Message}", LogHelper.LogType.Error);
return false;
}
}
/// <summary>
/// 注销所有快捷键
/// </summary>
public void UnregisterAllHotkeys()
{
try
{
if (_isDisposed)
return;
foreach (var hotkeyName in _registeredHotkeys.Keys)
{
try
{
HotkeyManager.Current.Remove(hotkeyName);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"注销快捷键 {hotkeyName} 时出错: {ex.Message}", LogHelper.LogType.Warning);
}
}
_registeredHotkeys.Clear();
LogHelper.WriteLogToFile("已注销所有全局快捷键", LogHelper.LogType.Event);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"注销所有快捷键时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 检查快捷键是否已注册
/// </summary>
/// <param name="hotkeyName">快捷键名称</param>
/// <returns>是否已注册</returns>
public bool IsHotkeyRegistered(string hotkeyName)
{
return _registeredHotkeys.ContainsKey(hotkeyName);
}
/// <summary>
/// 获取已注册的快捷键列表
/// </summary>
/// <returns>快捷键信息列表</returns>
public List<HotkeyInfo> GetRegisteredHotkeys()
{
return new List<HotkeyInfo>(_registeredHotkeys.Values);
}
/// <summary>
/// 注册默认快捷键集合
/// </summary>
public void RegisterDefaultHotkeys()
{
try
{
// 基本操作快捷键
RegisterHotkey("Undo", Key.Z, ModifierKeys.Control, () => _mainWindow.SymbolIconUndo_MouseUp(null, null));
RegisterHotkey("Redo", Key.Y, ModifierKeys.Control, () => _mainWindow.SymbolIconRedo_MouseUp(null, null));
RegisterHotkey("Clear", Key.E, ModifierKeys.Control, () => _mainWindow.SymbolIconDelete_MouseUp(null, null));
RegisterHotkey("Paste", Key.V, ModifierKeys.Control, () => _mainWindow.HandleGlobalPaste(null, null));
// 工具切换快捷键
RegisterHotkey("SelectTool", Key.S, ModifierKeys.Alt, () => _mainWindow.SymbolIconSelect_MouseUp(null, null));
RegisterHotkey("DrawTool", Key.D, ModifierKeys.Alt, () => _mainWindow.PenIcon_Click(null, null));
RegisterHotkey("EraserTool", Key.E, ModifierKeys.Alt, () => _mainWindow.EraserIcon_Click(null, null));
RegisterHotkey("BlackboardTool", Key.B, ModifierKeys.Alt, () => _mainWindow.ImageBlackboard_MouseUp(null, null));
RegisterHotkey("QuitDrawTool", Key.Q, ModifierKeys.Alt, () => _mainWindow.CursorIcon_Click(null, null));
// 画笔快捷键 - 使用反射访问penType字段
RegisterHotkey("Pen1", Key.D1, ModifierKeys.Alt, () => SwitchToPenType(0));
RegisterHotkey("Pen2", Key.D2, ModifierKeys.Alt, () => SwitchToPenType(1));
RegisterHotkey("Pen3", Key.D3, ModifierKeys.Alt, () => SwitchToPenType(2));
RegisterHotkey("Pen4", Key.D4, ModifierKeys.Alt, () => SwitchToPenType(3));
RegisterHotkey("Pen5", Key.D5, ModifierKeys.Alt, () => SwitchToPenType(4));
// 功能快捷键
RegisterHotkey("DrawLine", Key.L, ModifierKeys.Alt, () => _mainWindow.BtnDrawLine_Click(null, null));
RegisterHotkey("Screenshot", Key.C, ModifierKeys.Alt, () => _mainWindow.SaveScreenShotToDesktop());
RegisterHotkey("Hide", Key.V, ModifierKeys.Alt, () => _mainWindow.SymbolIconEmoji_MouseUp(null, null));
// 退出快捷键
RegisterHotkey("Exit", Key.Escape, ModifierKeys.None, () => _mainWindow.KeyExit(null, null));
LogHelper.WriteLogToFile("已注册默认全局快捷键集合", LogHelper.LogType.Event);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"注册默认快捷键时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 从设置加载快捷键配置
/// </summary>
public void LoadHotkeysFromSettings()
{
try
{
// 这里可以从配置文件或设置中加载自定义快捷键
// 暂时使用默认快捷键
RegisterDefaultHotkeys();
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"从设置加载快捷键时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 保存快捷键配置到设置
/// </summary>
public void SaveHotkeysToSettings()
{
try
{
// 这里可以将快捷键配置保存到配置文件或设置中
LogHelper.WriteLogToFile("快捷键配置已保存", LogHelper.LogType.Event);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"保存快捷键配置时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
#endregion
#region Private Helper Methods
/// <summary>
/// 切换到指定笔类型
/// </summary>
/// <param name="penTypeIndex">笔类型索引</param>
private void SwitchToPenType(int penTypeIndex)
{
try
{
// 通过反射访问主窗口的penType字段
var penTypeField = _mainWindow.GetType().GetField("penType",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (penTypeField != null)
{
penTypeField.SetValue(_mainWindow, penTypeIndex);
// 调用CheckPenTypeUIState方法更新UI状态
var checkPenTypeMethod = _mainWindow.GetType().GetMethod("CheckPenTypeUIState",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (checkPenTypeMethod != null)
{
checkPenTypeMethod.Invoke(_mainWindow, null);
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"切换到笔类型{penTypeIndex}时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
#endregion
#region IDisposable Implementation
public void Dispose()
{
if (!_isDisposed)
{
UnregisterAllHotkeys();
_isDisposed = true;
}
}
#endregion
#region Nested Classes
/// <summary>
/// 快捷键信息类
/// </summary>
public class HotkeyInfo
{
public string Name { get; set; }
public Key Key { get; set; }
public ModifierKeys Modifiers { get; set; }
public Action Action { get; set; }
public override string ToString()
{
var modifiersText = Modifiers == ModifierKeys.None ? "" : $"{Modifiers}+";
return $"{modifiersText}{Key}";
}
}
#endregion
}
}
+264
View File
@@ -0,0 +1,264 @@
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using System.Windows.Ink;
namespace Ink_Canvas.Helpers
{
/// <summary>
/// 墨迹渐隐管理器 - 管理墨迹的渐隐动画和状态
/// </summary>
public class InkFadeManager
{
#region Properties
/// <summary>
/// 是否启用墨迹渐隐功能
/// </summary>
public bool IsEnabled { get; set; } = false;
/// <summary>
/// 墨迹渐隐时间(毫秒)
/// </summary>
public int FadeTime { get; set; } = 3000;
/// <summary>
/// 渐隐动画持续时间(毫秒)
/// </summary>
public int AnimationDuration { get; set; } = 1000;
#endregion
#region Private Fields
private readonly MainWindow _mainWindow;
private readonly Dispatcher _dispatcher;
private readonly Dictionary<Stroke, DispatcherTimer> _fadeTimers;
private readonly Dictionary<Stroke, UIElement> _strokeVisuals;
#endregion
#region Constructor
public InkFadeManager(MainWindow mainWindow)
{
_mainWindow = mainWindow ?? throw new ArgumentNullException(nameof(mainWindow));
_dispatcher = _mainWindow.Dispatcher;
_fadeTimers = new Dictionary<Stroke, DispatcherTimer>();
_strokeVisuals = new Dictionary<Stroke, UIElement>();
}
#endregion
#region Public Methods
/// <summary>
/// 添加需要渐隐的墨迹
/// </summary>
/// <param name="stroke">墨迹对象</param>
/// <param name="visual">墨迹的视觉元素</param>
public void AddFadingStroke(Stroke stroke, UIElement visual)
{
if (!IsEnabled || stroke == null || visual == null) return;
try
{
// 记录墨迹和视觉元素的对应关系
_strokeVisuals[stroke] = visual;
// 创建定时器,在指定时间后开始渐隐动画
var timer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(FadeTime)
};
timer.Tick += (sender, e) =>
{
StartFadeAnimation(stroke);
timer.Stop();
_fadeTimers.Remove(stroke);
};
_fadeTimers[stroke] = timer;
timer.Start();
// 将视觉元素添加到画布上
_dispatcher.InvokeAsync(() =>
{
try
{
if (_mainWindow.inkCanvas != null)
{
_mainWindow.inkCanvas.Children.Add(visual);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"添加墨迹视觉元素到画布失败: {ex}", LogHelper.LogType.Error);
}
});
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"添加渐隐墨迹失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 移除墨迹
/// </summary>
/// <param name="stroke">要移除的墨迹</param>
public void RemoveStroke(Stroke stroke)
{
if (stroke == null) return;
try
{
if (_fadeTimers.TryGetValue(stroke, out var timer))
{
timer.Stop();
_fadeTimers.Remove(stroke);
}
if (_strokeVisuals.TryGetValue(stroke, out var visual))
{
_dispatcher.InvokeAsync(() =>
{
try
{
if (_mainWindow.inkCanvas != null && _mainWindow.inkCanvas.Children.Contains(visual))
{
_mainWindow.inkCanvas.Children.Remove(visual);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"从画布移除墨迹视觉元素失败: {ex}", LogHelper.LogType.Error);
}
});
_strokeVisuals.Remove(stroke);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"移除渐隐墨迹失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 清除所有渐隐墨迹
/// </summary>
public void ClearAllFadingStrokes()
{
try
{
foreach (var timer in _fadeTimers.Values)
{
timer.Stop();
}
_fadeTimers.Clear();
_dispatcher.InvokeAsync(() =>
{
try
{
if (_mainWindow.inkCanvas != null)
{
foreach (var visual in _strokeVisuals.Values)
{
if (_mainWindow.inkCanvas.Children.Contains(visual))
{
_mainWindow.inkCanvas.Children.Remove(visual);
}
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"清除所有墨迹视觉元素失败: {ex}", LogHelper.LogType.Error);
}
});
_strokeVisuals.Clear();
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"清除所有渐隐墨迹失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 更新渐隐时间设置
/// </summary>
/// <param name="fadeTime">新的渐隐时间(毫秒)</param>
public void UpdateFadeTime(int fadeTime)
{
FadeTime = fadeTime;
foreach (var kvp in _fadeTimers)
{
var stroke = kvp.Key;
var timer = kvp.Value;
timer.Stop();
timer.Interval = TimeSpan.FromMilliseconds(FadeTime);
timer.Start();
}
}
/// <summary>
/// 更新动画持续时间设置
/// </summary>
/// <param name="animationDuration">新的动画持续时间(毫秒)</param>
public void UpdateAnimationDuration(int animationDuration)
{
AnimationDuration = animationDuration;
}
#endregion
#region Private Methods
/// <summary>
/// 开始渐隐动画
/// </summary>
/// <param name="stroke">要渐隐的墨迹</param>
private void StartFadeAnimation(Stroke stroke)
{
if (!_strokeVisuals.TryGetValue(stroke, out var visual)) return;
try
{
_dispatcher.InvokeAsync(() =>
{
var fadeAnimation = new DoubleAnimation
{
From = 1.0,
To = 0.0,
Duration = TimeSpan.FromMilliseconds(AnimationDuration),
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseInOut }
};
fadeAnimation.Completed += (sender, e) =>
{
try
{
if (_mainWindow.inkCanvas != null && _mainWindow.inkCanvas.Children.Contains(visual))
{
_mainWindow.inkCanvas.Children.Remove(visual);
}
RemoveStroke(stroke);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"渐隐动画完成后清理墨迹失败: {ex}", LogHelper.LogType.Error);
}
};
visual.BeginAnimation(UIElement.OpacityProperty, fadeAnimation);
});
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"开始渐隐动画失败: {ex}", LogHelper.LogType.Error);
}
}
#endregion
}
}
-1
View File
@@ -3,7 +3,6 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using Ink_Canvas.Helpers;
namespace Ink_Canvas.Helpers
{
+55 -4
View File
@@ -42,6 +42,9 @@ namespace Ink_Canvas
private System.Windows.Controls.Canvas currentCanvas;
private AutoUpdateHelper.UpdateLineGroup AvailableLatestLineGroup;
// 全局快捷键管理器
private GlobalHotkeyManager _globalHotkeyManager;
#region Window Initialization
@@ -495,6 +498,9 @@ namespace Ink_Canvas
// 初始化剪贴板监控
InitializeClipboardMonitoring();
// 初始化全局快捷键管理器
InitializeGlobalHotkeyManager();
}
private void SystemEventsOnDisplaySettingsChanged(object sender, EventArgs e)
@@ -624,6 +630,13 @@ namespace Ink_Canvas
CleanupClipboardMonitoring();
ClipboardNotification.Stop();
// 清理全局快捷键管理器
if (_globalHotkeyManager != null)
{
_globalHotkeyManager.Dispose();
_globalHotkeyManager = null;
}
// 停止置顶维护定时器
StopTopmostMaintenance();
@@ -1067,10 +1080,7 @@ namespace Ink_Canvas
// 新增:快捷键设置
private void NavShortcuts_Click(object sender, RoutedEventArgs e)
{
// 切换到快捷键设置页面
ShowSettingsSection("shortcuts");
// 如果设置部分尚未快捷键
MessageBox.Show("设置功能正在开发中", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
OpenHotkeySettingsWindow();
}
private void BtnCloseSettings_Click(object sender, RoutedEventArgs e)
@@ -1955,5 +1965,46 @@ namespace Ink_Canvas
}
#endregion
#region
/// <summary>
/// 初始化全局快捷键管理器
/// </summary>
private void InitializeGlobalHotkeyManager()
{
try
{
_globalHotkeyManager = new GlobalHotkeyManager(this);
_globalHotkeyManager.LoadHotkeysFromSettings();
LogHelper.WriteLogToFile("全局快捷键管理器已初始化", LogHelper.LogType.Event);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"初始化全局快捷键管理器时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 打开快捷键设置窗口
/// </summary>
private void OpenHotkeySettingsWindow()
{
try
{
if (_globalHotkeyManager == null)
{
MessageBox.Show("快捷键管理器尚未初始化,请稍后重试。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
var hotkeySettingsWindow = new HotkeySettingsWindow(this, _globalHotkeyManager);
hotkeySettingsWindow.ShowDialog();
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"打开快捷键设置窗口时出错: {ex.Message}", LogHelper.LogType.Error);
MessageBox.Show($"打开快捷键设置窗口时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
#endregion
}
}
@@ -185,7 +185,7 @@ namespace Ink_Canvas
}
// 处理全局粘贴快捷键
private async void HandleGlobalPaste(object sender, ExecutedRoutedEventArgs e)
internal async void HandleGlobalPaste(object sender, ExecutedRoutedEventArgs e)
{
try
{
@@ -186,7 +186,7 @@ namespace Ink_Canvas
GridForFloatingBarDraging.Visibility = Visibility.Visible;
}
private void SymbolIconEmoji_MouseUp(object sender, MouseButtonEventArgs e)
internal void SymbolIconEmoji_MouseUp(object sender, MouseButtonEventArgs e)
{
isDragDropInEffect = false;
@@ -495,7 +495,8 @@ namespace Ink_Canvas
#endregion
#region
private void SymbolIconUndo_MouseUp(object sender, MouseButtonEventArgs e)
internal void SymbolIconUndo_MouseUp(object sender, MouseButtonEventArgs e)
{
//if (lastBorderMouseDownObject != sender) return;
@@ -508,7 +509,7 @@ namespace Ink_Canvas
HideSubPanels();
}
private void SymbolIconRedo_MouseUp(object sender, MouseButtonEventArgs e)
internal void SymbolIconRedo_MouseUp(object sender, MouseButtonEventArgs e)
{
//if (lastBorderMouseDownObject != sender) return;
@@ -528,7 +529,7 @@ namespace Ink_Canvas
//private bool Not_Enter_Blackboard_fir_Mouse_Click = true;
private bool isDisplayingOrHidingBlackboard;
private void ImageBlackboard_MouseUp(object sender, MouseButtonEventArgs e)
internal void ImageBlackboard_MouseUp(object sender, MouseButtonEventArgs e)
{
if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel)
@@ -728,7 +729,7 @@ namespace Ink_Canvas
#region
private void SymbolIconDelete_MouseUp(object sender, MouseButtonEventArgs e)
internal void SymbolIconDelete_MouseUp(object sender, MouseButtonEventArgs e)
{
if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel)
@@ -778,7 +779,7 @@ namespace Ink_Canvas
/// </summary>
/// <param name="sender">sender</param>
/// <param name="e">MouseButtonEventArgs</param>
private void SymbolIconSelect_MouseUp(object sender, MouseButtonEventArgs e)
internal void SymbolIconSelect_MouseUp(object sender, MouseButtonEventArgs e)
{
if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel)
@@ -1542,7 +1543,7 @@ namespace Ink_Canvas
});
}
private async void CursorIcon_Click(object sender, RoutedEventArgs e)
internal async void CursorIcon_Click(object sender, RoutedEventArgs e)
{
if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel)
((Panel)lastBorderMouseDownObject).Background = new SolidColorBrush(Colors.Transparent);
@@ -1648,7 +1649,7 @@ namespace Ink_Canvas
}
}
private void PenIcon_Click(object sender, RoutedEventArgs e)
internal void PenIcon_Click(object sender, RoutedEventArgs e)
{
if (lastBorderMouseDownObject != null && lastBorderMouseDownObject is Panel)
@@ -1866,7 +1867,7 @@ namespace Ink_Canvas
CheckColorTheme();
}
private void EraserIcon_Click(object sender, RoutedEventArgs e)
internal void EraserIcon_Click(object sender, RoutedEventArgs e)
{
EnterMultiTouchModeIfNeeded();
bool isAlreadyEraser = inkCanvas.EditingMode == InkCanvasEditingMode.EraseByPoint;
+1 -1
View File
@@ -57,7 +57,7 @@ namespace Ink_Canvas
}
private void KeyExit(object sender, ExecutedRoutedEventArgs e)
internal void KeyExit(object sender, ExecutedRoutedEventArgs e)
{
if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) BtnPPTSlideShowEnd_Click(BtnPPTSlideShowEnd, null);
}
+1 -1
View File
@@ -42,7 +42,7 @@ namespace Ink_Canvas
SaveInkCanvasStrokes(false);
}
private void SaveScreenShotToDesktop()
internal void SaveScreenShotToDesktop()
{
var desktopPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory),
+1 -1
View File
@@ -173,7 +173,7 @@ namespace Ink_Canvas
return Task.FromResult(true);
}
private async void BtnDrawLine_Click(object sender, MouseButtonEventArgs e)
internal async void BtnDrawLine_Click(object sender, MouseButtonEventArgs e)
{
await CheckIsDrawingShapesInMultiTouchMode();
EnterShapeDrawingMode(1);
+65
View File
@@ -0,0 +1,65 @@
<UserControl x:Class="Ink_Canvas.Windows.HotkeyItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
mc:Ignorable="d"
d:DesignHeight="60" d:DesignWidth="600">
<Border Background="White"
BorderBrush="#E0E0E0"
BorderThickness="1"
CornerRadius="5"
Margin="0,2">
<Grid Margin="15,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- 左侧信息 -->
<ui:SimpleStackPanel Grid.Column="0" VerticalAlignment="Center">
<TextBlock x:Name="TitleTextBlock"
Text="快捷键标题"
FontSize="14"
FontWeight="SemiBold"
Foreground="#333333"/>
<TextBlock x:Name="DescriptionTextBlock"
Text="快捷键描述"
FontSize="12"
Foreground="#666666"
Margin="0,2,0,0"/>
</ui:SimpleStackPanel>
<!-- 当前快捷键显示 -->
<Border Grid.Column="1"
Background="#F5F5F5"
BorderBrush="#D0D0D0"
BorderThickness="1"
CornerRadius="3"
Margin="10,0,0,0"
Padding="8,4">
<TextBlock x:Name="CurrentHotkeyTextBlock"
Text="未设置"
FontSize="12"
Foreground="#666666"
MinWidth="80"
TextAlignment="Center"/>
</Border>
<!-- 设置按钮 -->
<Button x:Name="BtnSetHotkey"
Grid.Column="2"
Content="设置"
Width="60"
Height="28"
Background="#0066BF"
Foreground="White"
FontSize="12"
Margin="10,0,0,0"
Click="BtnSetHotkey_Click"/>
</Grid>
</Border>
</UserControl>
+166
View File
@@ -0,0 +1,166 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace Ink_Canvas.Windows
{
/// <summary>
/// 快捷键项控件
/// </summary>
public partial class HotkeyItem : UserControl
{
#region Events
/// <summary>
/// 快捷键变更事件
/// </summary>
public event EventHandler<HotkeyChangedEventArgs> HotkeyChanged;
#endregion
#region Properties
public string Title
{
get => TitleTextBlock.Text;
set => TitleTextBlock.Text = value;
}
public string Description
{
get => DescriptionTextBlock.Text;
set => DescriptionTextBlock.Text = value;
}
public string DefaultKey { get; set; }
public string DefaultModifiers { get; set; }
private Key _currentKey = Key.None;
private ModifierKeys _currentModifiers = ModifierKeys.None;
#endregion
#region Constructor
public HotkeyItem()
{
InitializeComponent();
UpdateHotkeyDisplay();
}
#endregion
#region Public Methods
/// <summary>
/// 设置当前快捷键
/// </summary>
/// <param name="key">按键</param>
/// <param name="modifiers">修饰键</param>
public void SetCurrentHotkey(Key key, ModifierKeys modifiers)
{
_currentKey = key;
_currentModifiers = modifiers;
UpdateHotkeyDisplay();
}
/// <summary>
/// 获取当前快捷键
/// </summary>
/// <returns>快捷键信息</returns>
public (Key key, ModifierKeys modifiers) GetCurrentHotkey()
{
return (_currentKey, _currentModifiers);
}
#endregion
#region Private Methods
private void UpdateHotkeyDisplay()
{
if (_currentKey == Key.None)
{
CurrentHotkeyTextBlock.Text = "未设置";
CurrentHotkeyTextBlock.Foreground = System.Windows.Media.Brushes.Gray;
}
else
{
var modifiersText = _currentModifiers == ModifierKeys.None ? "" : $"{_currentModifiers}+";
CurrentHotkeyTextBlock.Text = $"{modifiersText}{_currentKey}";
CurrentHotkeyTextBlock.Foreground = System.Windows.Media.Brushes.Black;
}
}
private void StartHotkeyCapture()
{
BtnSetHotkey.Content = "请按键...";
BtnSetHotkey.Background = System.Windows.Media.Brushes.Orange;
// 设置焦点以捕获键盘事件
Focus();
// 添加键盘事件处理器
KeyDown += HotkeyItem_KeyDown;
KeyUp += HotkeyItem_KeyUp;
}
private void StopHotkeyCapture()
{
BtnSetHotkey.Content = "设置";
BtnSetHotkey.Background = System.Windows.Media.Brushes.DodgerBlue;
// 移除键盘事件处理器
KeyDown -= HotkeyItem_KeyDown;
KeyUp -= HotkeyItem_KeyUp;
}
private void HotkeyItem_KeyDown(object sender, KeyEventArgs e)
{
e.Handled = true;
// 忽略某些特殊键
if (e.Key == Key.LeftShift || e.Key == Key.RightShift ||
e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl ||
e.Key == Key.LeftAlt || e.Key == Key.RightAlt ||
e.Key == Key.LWin || e.Key == Key.RWin)
{
return;
}
// 获取修饰键
var modifiers = ModifierKeys.None;
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
modifiers |= ModifierKeys.Control;
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
modifiers |= ModifierKeys.Shift;
if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
modifiers |= ModifierKeys.Alt;
if (Keyboard.IsKeyDown(Key.LWin) || Keyboard.IsKeyDown(Key.RWin))
modifiers |= ModifierKeys.Windows;
// 设置新的快捷键
var oldKey = _currentKey;
var oldModifiers = _currentModifiers;
_currentKey = e.Key;
_currentModifiers = modifiers;
UpdateHotkeyDisplay();
StopHotkeyCapture();
// 触发快捷键变更事件
HotkeyChanged?.Invoke(this, new HotkeyChangedEventArgs
{
HotkeyName = Title,
Key = _currentKey,
Modifiers = _currentModifiers
});
}
private void HotkeyItem_KeyUp(object sender, KeyEventArgs e)
{
e.Handled = true;
}
#endregion
#region Event Handlers
private void BtnSetHotkey_Click(object sender, RoutedEventArgs e)
{
StartHotkeyCapture();
}
#endregion
}
}
@@ -0,0 +1,191 @@
<Window x:Class="Ink_Canvas.Windows.HotkeySettingsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Ink_Canvas.Windows"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
ui:ThemeManager.RequestedTheme="Light"
Topmost="True"
Background="Transparent"
AllowsTransparency="True"
mc:Ignorable="d"
WindowStyle="None"
WindowStartupLocation="CenterScreen"
Title="快捷键设置"
Height="600"
Width="800">
<Border Background="#F0F3F9" CornerRadius="10" BorderThickness="1" BorderBrush="#0066BF" Margin="10">
<Grid>
<!-- 标题栏 -->
<Border Height="50" Background="#0066BF" CornerRadius="10,10,0,0" VerticalAlignment="Top">
<Grid>
<TextBlock Text="快捷键设置"
Foreground="White"
FontSize="18"
FontWeight="Bold"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<Button x:Name="BtnClose"
Content="✕"
Width="30"
Height="30"
Background="Transparent"
Foreground="White"
FontSize="14"
HorizontalAlignment="Right"
Margin="0,0,30,0"
Click="BtnClose_Click"/>
</Grid>
</Border>
<!-- 内容区域 -->
<ScrollViewer Margin="0,50,0,0" VerticalScrollBarVisibility="Auto">
<ui:SimpleStackPanel Margin="20">
<!-- 说明文字 -->
<TextBlock Text="在这里可以自定义全局快捷键设置。全局快捷键在任何情况下都能生效,即使应用程序不在焦点状态。"
TextWrapping="Wrap"
Margin="0,0,0,20"
Foreground="#666666"/>
<!-- 快捷键列表 -->
<ui:SimpleStackPanel x:Name="HotkeyList" Margin="0,0,0,20">
<!-- 基本操作 -->
<GroupBox Header="基本操作" Margin="0,0,0,15">
<ui:SimpleStackPanel>
<local:HotkeyItem x:Name="UndoHotkey"
Title="撤销"
Description="撤销上一步操作"
DefaultKey="Z"
DefaultModifiers="Control"/>
<local:HotkeyItem x:Name="RedoHotkey"
Title="重做"
Description="重做上一步操作"
DefaultKey="Y"
DefaultModifiers="Control"/>
<local:HotkeyItem x:Name="ClearHotkey"
Title="清空"
Description="清空当前画板内容"
DefaultKey="E"
DefaultModifiers="Control"/>
<local:HotkeyItem x:Name="PasteHotkey"
Title="粘贴"
Description="粘贴剪贴板内容"
DefaultKey="V"
DefaultModifiers="Control"/>
</ui:SimpleStackPanel>
</GroupBox>
<!-- 工具切换 -->
<GroupBox Header="工具切换" Margin="0,0,0,15">
<ui:SimpleStackPanel>
<local:HotkeyItem x:Name="SelectToolHotkey"
Title="选择工具"
Description="切换到选择工具"
DefaultKey="S"
DefaultModifiers="Alt"/>
<local:HotkeyItem x:Name="DrawToolHotkey"
Title="绘图工具"
Description="切换到绘图工具"
DefaultKey="D"
DefaultModifiers="Alt"/>
<local:HotkeyItem x:Name="EraserToolHotkey"
Title="橡皮擦工具"
Description="切换到橡皮擦工具"
DefaultKey="E"
DefaultModifiers="Alt"/>
<local:HotkeyItem x:Name="BlackboardToolHotkey"
Title="黑板工具"
Description="切换到黑板工具"
DefaultKey="B"
DefaultModifiers="Alt"/>
<local:HotkeyItem x:Name="QuitDrawToolHotkey"
Title="退出绘图"
Description="退出绘图模式"
DefaultKey="Q"
DefaultModifiers="Alt"/>
</ui:SimpleStackPanel>
</GroupBox>
<!-- 画笔设置 -->
<GroupBox Header="画笔设置" Margin="0,0,0,15">
<ui:SimpleStackPanel>
<local:HotkeyItem x:Name="Pen1Hotkey"
Title="画笔1"
Description="选择画笔1"
DefaultKey="D1"
DefaultModifiers="Alt"/>
<local:HotkeyItem x:Name="Pen2Hotkey"
Title="画笔2"
Description="选择画笔2"
DefaultKey="D2"
DefaultModifiers="Alt"/>
<local:HotkeyItem x:Name="Pen3Hotkey"
Title="画笔3"
Description="选择画笔3"
DefaultKey="D3"
DefaultModifiers="Alt"/>
<local:HotkeyItem x:Name="Pen4Hotkey"
Title="画笔4"
Description="选择画笔4"
DefaultKey="D4"
DefaultModifiers="Alt"/>
<local:HotkeyItem x:Name="Pen5Hotkey"
Title="画笔5"
Description="选择画笔5"
DefaultKey="D5"
DefaultModifiers="Alt"/>
</ui:SimpleStackPanel>
</GroupBox>
<!-- 功能快捷键 -->
<GroupBox Header="功能快捷键" Margin="0,0,0,15">
<ui:SimpleStackPanel>
<local:HotkeyItem x:Name="DrawLineHotkey"
Title="绘制直线"
Description="绘制直线工具"
DefaultKey="L"
DefaultModifiers="Alt"/>
<local:HotkeyItem x:Name="ScreenshotHotkey"
Title="截图"
Description="保存屏幕截图到桌面"
DefaultKey="C"
DefaultModifiers="Alt"/>
<local:HotkeyItem x:Name="HideHotkey"
Title="隐藏"
Description="隐藏应用程序"
DefaultKey="V"
DefaultModifiers="Alt"/>
<local:HotkeyItem x:Name="ExitHotkey"
Title="退出"
Description="退出当前模式或应用程序"
DefaultKey="Escape"
DefaultModifiers="None"/>
</ui:SimpleStackPanel>
</GroupBox>
</ui:SimpleStackPanel>
</ui:SimpleStackPanel>
</ScrollViewer>
<!-- 底部按钮 -->
<Border Height="60" Background="#F8F9FA" CornerRadius="0,0,10,10" VerticalAlignment="Bottom">
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,20,0">
<Button x:Name="BtnResetToDefault"
Content="重置为默认"
Width="100"
Height="35"
Margin="0,0,10,0"
Click="BtnResetToDefault_Click"/>
<Button x:Name="BtnSave"
Content="保存设置"
Width="100"
Height="35"
Background="#0066BF"
Foreground="White"
Click="BtnSave_Click"/>
</ui:SimpleStackPanel>
</Border>
</Grid>
</Border>
</Window>
@@ -0,0 +1,357 @@
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using Ink_Canvas.Helpers;
namespace Ink_Canvas.Windows
{
/// <summary>
/// 快捷键设置窗口
/// </summary>
public partial class HotkeySettingsWindow : Window
{
#region Private Fields
private readonly MainWindow _mainWindow;
private readonly GlobalHotkeyManager _hotkeyManager;
private readonly Dictionary<string, HotkeyItem> _hotkeyItems;
#endregion
#region Constructor
public HotkeySettingsWindow(MainWindow mainWindow, GlobalHotkeyManager hotkeyManager)
{
InitializeComponent();
_mainWindow = mainWindow;
_hotkeyManager = hotkeyManager;
_hotkeyItems = new Dictionary<string, HotkeyItem>();
// 隐藏主窗口的设置页面
HideMainWindowSettings();
InitializeHotkeyItems();
LoadCurrentHotkeys();
SetupEventHandlers();
// 注册窗口关闭事件
this.Closed += HotkeySettingsWindow_Closed;
}
#endregion
#region Private Methods
private void InitializeHotkeyItems()
{
// 初始化快捷键项
_hotkeyItems["Undo"] = UndoHotkey;
_hotkeyItems["Redo"] = RedoHotkey;
_hotkeyItems["Clear"] = ClearHotkey;
_hotkeyItems["Paste"] = PasteHotkey;
_hotkeyItems["SelectTool"] = SelectToolHotkey;
_hotkeyItems["DrawTool"] = DrawToolHotkey;
_hotkeyItems["EraserTool"] = EraserToolHotkey;
_hotkeyItems["BlackboardTool"] = BlackboardToolHotkey;
_hotkeyItems["QuitDrawTool"] = QuitDrawToolHotkey;
_hotkeyItems["Pen1"] = Pen1Hotkey;
_hotkeyItems["Pen2"] = Pen2Hotkey;
_hotkeyItems["Pen3"] = Pen3Hotkey;
_hotkeyItems["Pen4"] = Pen4Hotkey;
_hotkeyItems["Pen5"] = Pen5Hotkey;
_hotkeyItems["DrawLine"] = DrawLineHotkey;
_hotkeyItems["Screenshot"] = ScreenshotHotkey;
_hotkeyItems["Hide"] = HideHotkey;
_hotkeyItems["Exit"] = ExitHotkey;
}
private void LoadCurrentHotkeys()
{
try
{
var registeredHotkeys = _hotkeyManager.GetRegisteredHotkeys();
foreach (var hotkey in registeredHotkeys)
{
if (_hotkeyItems.TryGetValue(hotkey.Name, out var hotkeyItem))
{
hotkeyItem.SetCurrentHotkey(hotkey.Key, hotkey.Modifiers);
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"加载当前快捷键时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
private void SetupEventHandlers()
{
// 为每个快捷键项设置事件处理器
foreach (var hotkeyItem in _hotkeyItems.Values)
{
hotkeyItem.HotkeyChanged += OnHotkeyChanged;
}
}
private void OnHotkeyChanged(object sender, HotkeyChangedEventArgs e)
{
try
{
// 检查快捷键冲突
if (IsHotkeyConflict(e.Key, e.Modifiers, e.HotkeyName))
{
MessageBox.Show($"快捷键 {e.Modifiers}+{e.Key} 已被其他功能使用,请选择其他组合。",
"快捷键冲突", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
// 更新快捷键管理器
UpdateHotkeyInManager(e.HotkeyName, e.Key, e.Modifiers);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"处理快捷键变更时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
private bool IsHotkeyConflict(Key key, ModifierKeys modifiers, string excludeHotkeyName)
{
var registeredHotkeys = _hotkeyManager.GetRegisteredHotkeys();
foreach (var hotkey in registeredHotkeys)
{
if (hotkey.Name != excludeHotkeyName &&
hotkey.Key == key &&
hotkey.Modifiers == modifiers)
{
return true;
}
}
return false;
}
private void UpdateHotkeyInManager(string hotkeyName, Key key, ModifierKeys modifiers)
{
try
{
// 根据快捷键名称获取对应的动作
var action = GetActionForHotkey(hotkeyName);
if (action != null)
{
_hotkeyManager.RegisterHotkey(hotkeyName, key, modifiers, action);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"更新快捷键管理器时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
private Action GetActionForHotkey(string hotkeyName)
{
switch (hotkeyName)
{
case "Undo":
return () => _mainWindow.SymbolIconUndo_MouseUp(null, null);
case "Redo":
return () => _mainWindow.SymbolIconRedo_MouseUp(null, null);
case "Clear":
return () => _mainWindow.SymbolIconDelete_MouseUp(null, null);
case "Paste":
return () => _mainWindow.HandleGlobalPaste(null, null);
case "SelectTool":
return () => _mainWindow.SymbolIconSelect_MouseUp(null, null);
case "DrawTool":
return () => _mainWindow.PenIcon_Click(null, null);
case "EraserTool":
return () => _mainWindow.EraserIcon_Click(null, null);
case "BlackboardTool":
return () => _mainWindow.ImageBlackboard_MouseUp(null, null);
case "QuitDrawTool":
return () => _mainWindow.CursorIcon_Click(null, null);
case "Pen1":
return () => SwitchToPenType(0);
case "Pen2":
return () => SwitchToPenType(1);
case "Pen3":
return () => SwitchToPenType(2);
case "Pen4":
return () => SwitchToPenType(3);
case "Pen5":
return () => SwitchToPenType(4);
case "DrawLine":
return () => _mainWindow.BtnDrawLine_Click(null, null);
case "Screenshot":
return () => _mainWindow.SaveScreenShotToDesktop();
case "Hide":
return () => _mainWindow.SymbolIconEmoji_MouseUp(null, null);
case "Exit":
return () => _mainWindow.KeyExit(null, null);
default:
return null;
}
}
/// <summary>
/// 切换到指定笔类型
/// </summary>
/// <param name="penTypeIndex">笔类型索引</param>
private void SwitchToPenType(int penTypeIndex)
{
try
{
// 通过反射访问主窗口的penType字段
var penTypeField = _mainWindow.GetType().GetField("penType",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (penTypeField != null)
{
penTypeField.SetValue(_mainWindow, penTypeIndex);
// 调用CheckPenTypeUIState方法更新UI状态
var checkPenTypeMethod = _mainWindow.GetType().GetMethod("CheckPenTypeUIState",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (checkPenTypeMethod != null)
{
checkPenTypeMethod.Invoke(_mainWindow, null);
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"切换到笔类型{penTypeIndex}时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
#endregion
#region MainWindow Settings Management
/// <summary>
/// 隐藏主窗口的设置页面
/// </summary>
private void HideMainWindowSettings()
{
try
{
// 通过反射访问主窗口的设置面板
var settingsBorder = _mainWindow.GetType().GetField("BorderSettings",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(_mainWindow) as System.Windows.Controls.Border;
if (settingsBorder != null)
{
settingsBorder.Visibility = System.Windows.Visibility.Collapsed;
}
// 隐藏设置蒙版
var settingsMask = _mainWindow.GetType().GetField("BorderSettingsMask",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(_mainWindow) as System.Windows.Controls.Border;
if (settingsMask != null)
{
settingsMask.Visibility = System.Windows.Visibility.Collapsed;
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"隐藏主窗口设置页面时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 显示主窗口的设置页面
/// </summary>
private void ShowMainWindowSettings()
{
try
{
// 通过反射访问主窗口的设置面板
var settingsBorder = _mainWindow.GetType().GetField("BorderSettings",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(_mainWindow) as System.Windows.Controls.Border;
if (settingsBorder != null)
{
settingsBorder.Visibility = System.Windows.Visibility.Visible;
}
// 显示设置蒙版
var settingsMask = _mainWindow.GetType().GetField("BorderSettingsMask",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(_mainWindow) as System.Windows.Controls.Border;
if (settingsMask != null)
{
settingsMask.Visibility = System.Windows.Visibility.Visible;
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"显示主窗口设置页面时出错: {ex.Message}", LogHelper.LogType.Error);
}
}
#endregion
#region Window Event Handlers
/// <summary>
/// 窗口关闭事件处理
/// </summary>
private void HotkeySettingsWindow_Closed(object sender, EventArgs e)
{
// 恢复主窗口设置页面的显示
ShowMainWindowSettings();
}
#endregion
#region Event Handlers
private void BtnClose_Click(object sender, RoutedEventArgs e)
{
Close();
}
private void BtnResetToDefault_Click(object sender, RoutedEventArgs e)
{
try
{
var result = MessageBox.Show("确定要重置所有快捷键为默认设置吗?",
"确认重置", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
// 重置为默认快捷键
_hotkeyManager.RegisterDefaultHotkeys();
// 更新UI显示
LoadCurrentHotkeys();
MessageBox.Show("快捷键已重置为默认设置。", "重置完成", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"重置快捷键时出错: {ex.Message}", LogHelper.LogType.Error);
MessageBox.Show($"重置快捷键时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void BtnSave_Click(object sender, RoutedEventArgs e)
{
try
{
// 保存快捷键配置
_hotkeyManager.SaveHotkeysToSettings();
MessageBox.Show("快捷键设置已保存。", "保存成功", MessageBoxButton.OK, MessageBoxImage.Information);
Close();
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"保存快捷键设置时出错: {ex.Message}", LogHelper.LogType.Error);
MessageBox.Show($"保存快捷键设置时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
#endregion
}
#region Hotkey Changed Event Args
/// <summary>
/// 快捷键变更事件参数
/// </summary>
public class HotkeyChangedEventArgs : EventArgs
{
public string HotkeyName { get; set; }
public Key Key { get; set; }
public ModifierKeys Modifiers { get; set; }
}
#endregion
}