From f53ef87a5d142a69d73a1a2d9085f04506e7bcc4 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Fri, 28 Jun 2019 23:57:30 +0800 Subject: [PATCH] updated the branch --- .../HandyControlDemo_Shared/MainWindow.xaml | 48 ++++---- .../MainWindow.xaml.cs | 3 - .../Tools/GlobalShortcut.cs | 113 ++++++++++++++---- 3 files changed, 112 insertions(+), 52 deletions(-) diff --git a/src/Shared/HandyControlDemo_Shared/MainWindow.xaml b/src/Shared/HandyControlDemo_Shared/MainWindow.xaml index ca38791a..34bee576 100644 --- a/src/Shared/HandyControlDemo_Shared/MainWindow.xaml +++ b/src/Shared/HandyControlDemo_Shared/MainWindow.xaml @@ -1,28 +1,28 @@  + 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:hc="https://handyorg.github.io/handycontrol" + xmlns:userControl="clr-namespace:HandyControlDemo.UserControl" + xmlns:data="clr-namespace:HandyControlDemo.Data" + mc:Ignorable="d" + BorderThickness="1" + BorderBrush="#262e2f" + NonClientAreaBackground="#262e2f" + OtherButtonHoverBackground="#888580" + CloseButtonForeground="White" + OtherButtonHoverForeground="White" + OtherButtonForeground="White" + Style="{StaticResource WindowBlur}" + Title="MainWindow" + ResizeMode="CanResizeWithGrip" + WindowStartupLocation="CenterScreen" + hc:GlobalShortcut.Host="True" + DataContext="{Binding Main,Source={StaticResource Locator}}" + hc:Dialog.Token="{x:Static data:MessageToken.MainWindow}" + d:DesignHeight="800" + d:DesignWidth="1400"> diff --git a/src/Shared/HandyControlDemo_Shared/MainWindow.xaml.cs b/src/Shared/HandyControlDemo_Shared/MainWindow.xaml.cs index 5b5db38e..ec24646f 100644 --- a/src/Shared/HandyControlDemo_Shared/MainWindow.xaml.cs +++ b/src/Shared/HandyControlDemo_Shared/MainWindow.xaml.cs @@ -2,7 +2,6 @@ using System.ComponentModel; using GalaSoft.MvvmLight.Messaging; using HandyControl.Controls; -using HandyControl.Tools; using HandyControlDemo.Data; using HandyControlDemo.Tools; @@ -22,8 +21,6 @@ namespace HandyControlDemo Messenger.Default.Send(null, MessageToken.ClearLeftSelected); Messenger.Default.Send(true, MessageToken.FullSwitch); Messenger.Default.Send(AssemblyHelper.CreateInternalInstance($"UserControl.{MessageToken.OverView}"), MessageToken.LoadShowContent); - - GlobalShortcut.Init(this); } protected override void OnClosing(CancelEventArgs e) diff --git a/src/Shared/HandyControl_Shared/Tools/GlobalShortcut.cs b/src/Shared/HandyControl_Shared/Tools/GlobalShortcut.cs index 62b0c7b8..3946d575 100644 --- a/src/Shared/HandyControl_Shared/Tools/GlobalShortcut.cs +++ b/src/Shared/HandyControl_Shared/Tools/GlobalShortcut.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; -using System.Linq; +using System.Collections.ObjectModel; +using System.Collections.Specialized; using System.Windows; using System.Windows.Input; using HandyControl.Data; @@ -9,28 +10,39 @@ namespace HandyControl.Tools { public class GlobalShortcut { - private static readonly HashSet InputBindingCollectionSet = new HashSet(); + private static ObservableCollection KeyBindingCollection; + + private static readonly Dictionary CommandDic = new Dictionary(); + + private static void KeyboardHook_KeyDown(object sender, KeyboardHookEventArgs e) => HitTest(e.Key); static GlobalShortcut() { - KeyboardHook.KeyDown += KeyboardHook_KeyDown; - KeyboardHook.Start(); - } - private static void KeyboardHook_KeyDown(object sender, KeyboardHookEventArgs e) => HitTest(e.Key); + KeyboardHook.KeyDown += KeyboardHook_KeyDown; + } private static void HitTest(Key key) { if (IsModifierKey(key)) return; - var keyBindings = InputBindingCollectionSet - .SelectMany(inputBindingCollection => inputBindingCollection.OfType()) - .Where(keyBinding => keyBinding.Key != Key.None && keyBinding.Modifiers == Keyboard.Modifiers && keyBinding.Key == key); - keyBindings.ToList().ForEach(keyBinding => + var modifierKeys = Keyboard.Modifiers; + var keyStr = modifierKeys != ModifierKeys.None ? $"{modifierKeys.ToString()}, {key.ToString()}" : key.ToString(); + ExecuteCommand(keyStr); + } + + private static void ExecuteCommand(string key) + { + if (string.IsNullOrEmpty(key)) return; + if (CommandDic.ContainsKey(key)) { - if (keyBinding.Command?.CanExecute(keyBinding.CommandParameter) == true) - keyBinding.Command?.Execute(keyBinding.CommandParameter); - }); + var keyBinding = CommandDic[key]; + var command = keyBinding.Command; + if (command != null && command.CanExecute(keyBinding.CommandParameter)) + { + command.Execute(keyBinding.CommandParameter); + } + } } private static bool IsModifierKey(Key key) @@ -39,25 +51,76 @@ namespace HandyControl.Tools key == Key.RightCtrl || key == Key.RightAlt || key == Key.RightShift || key == Key.RWin; } - [Obsolete] + [Obsolete("pls use Host attach property instead of Init method")] public static void Init(DependencyObject host) { + CommandDic.Clear(); + + if (host == null) return; + + KeyBindingCollection = GetKeyBindings(host); + if (KeyBindingCollection == null || KeyBindingCollection.Count == 0) return; + + AddKeyBindings(KeyBindingCollection); + + KeyboardHook.Start(); } + private static void AddKeyBindings(IEnumerable keyBindings) + { + foreach (var item in keyBindings) + { + if (item.Key == Key.None) continue; + + if (item.Modifiers == ModifierKeys.None) + { + CommandDic[item.Key.ToString()] = item; + } + else + { + var keyStr = $"{item.Modifiers.ToString()}, {item.Key.ToString()}"; + CommandDic[keyStr] = item; + } + } + } + + public static readonly DependencyProperty HostProperty = DependencyProperty.RegisterAttached( + "Host", typeof(bool), typeof(GlobalShortcut), new PropertyMetadata(ValueBoxes.FalseBox, OnHostChanged)); + + private static void OnHostChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (DesignerHelper.IsInDesignMode) return; + + if (KeyBindingCollection != null) + { + KeyBindingCollection.CollectionChanged -= KeyBindingCollection_CollectionChanged; + } + KeyBindingCollection = GetKeyBindings(d); + if (KeyBindingCollection != null) + { + KeyBindingCollection.CollectionChanged += KeyBindingCollection_CollectionChanged; + } + } + + private static void KeyBindingCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + AddKeyBindings(KeyBindingCollection); + KeyboardHook.Start(); + } + + public static void SetHost(DependencyObject element, bool value) + => element.SetValue(HostProperty, value); + + public static bool GetHost(DependencyObject element) + => (bool) element.GetValue(HostProperty); + public static readonly DependencyProperty KeyBindingsProperty = DependencyProperty.RegisterAttached( - "KeyBindings", typeof(InputBindingCollection), typeof(GlobalShortcut), new PropertyMetadata(new InputBindingCollection()), OnValidateValue); + "KeyBindings", typeof(ObservableCollection), typeof(GlobalShortcut), new PropertyMetadata(new ObservableCollection())); - private static bool OnValidateValue(object value) - { - if (value is InputBindingCollection inputBindingCollection && !InputBindingCollectionSet.Contains(inputBindingCollection)) - InputBindingCollectionSet.Add(inputBindingCollection); - return true; - } - - public static void SetKeyBindings(DependencyObject element, InputBindingCollection value) + public static void SetKeyBindings(DependencyObject element, ObservableCollection value) => element.SetValue(KeyBindingsProperty, value); - public static InputBindingCollection GetKeyBindings(DependencyObject element) - => (InputBindingCollection)element.GetValue(KeyBindingsProperty); + public static ObservableCollection GetKeyBindings(DependencyObject element) + => (ObservableCollection) element.GetValue(KeyBindingsProperty); } } \ No newline at end of file