[英]WPF determine all keys released in textbox?
I wanted to make user to customise the shortcut keys, so I'm using a textbox to get the key input.我想让用户自定义快捷键,所以我使用文本框来获取键输入。 The expected state should be to save the key when pressed, and show KeyGesture string when released.
预期的 state 应该是在按下时保存键,并在释放时显示 KeyGesture 字符串。
But some keys will be responded to by other registered hotkeys ( like Ctrl+A, win+G etc. ), unable to determine whether if the keys are all released, so that cannot clear ModifierKeys when appropriate.但有些按键会被其他注册的热键(如Ctrl+A、win+G等)响应,无法判断按键是否全部释放,因此无法在适当的时候清除ModifierKeys。
Here's my code, if input a registered hotkey this keyCount will be wrong:这是我的代码,如果输入一个注册的热键,这个keyCount将是错误的:
KeyGestureConverter keyGestureConverter = new KeyGestureConverter();
Key key;
ModifierKeys modifierKeys;
int keyCount = 0;
private void HotKeyTextbox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key.Equals(Key.LeftCtrl) || e.Key.Equals(Key.RightCtrl))
modifierKeys |= ModifierKeys.Control;
else if (e.Key.Equals(Key.LeftAlt) || e.Key.Equals(Key.RightAlt))
modifierKeys |= ModifierKeys.Alt;
else if (e.Key.Equals(Key.LeftShift) || e.Key.Equals(Key.RightShift))
modifierKeys |= ModifierKeys.Shift;
else if (e.Key.Equals(Key.LWin) || e.Key.Equals(Key.RWin))
modifierKeys |= ModifierKeys.Windows;
else
key = e.Key;
keyCount++;
}
private void HotKeyTextbox_KeyUp(object sender, KeyEventArgs e)
{
keyCount--;
try
{
KeyGesture keyGesture = new KeyGesture(key, modifierKeys);
HotKeyTextbox.Text = keyGestureConverter.ConvertToString(keyGesture);
}
catch
{
HotKeyTextbox.Text = string.Empty;
}
if (keyCount <= 0)
{
keyCount = 0;
key = Key.None;
modifierKeys = ModifierKeys.None;
}
}
How about achieving the right effect?如何达到正确的效果?
EDIT: misunderstood the question, this is for when shortcuts have already been recorded.编辑:误解了这个问题,这是针对已经记录了快捷方式的情况。
private void Key_Down(object sender, System.Windows.Input.KeyEventArgs e)
{
if (Keyboard.Modifiers == ModifierKeys.Control) // With CTRL
{
switch (e.Key)
{
case Key.Escape:
Close();
break;
case Key.Y:
Validate_Data();
break;
}
}
else // Without CRTL
{
switch (e.Key)
{
case Key.Escape:
Close();
break;
}
}
}
You must handle the PreviewKeyDown
and PreviewKeyUp
events to catch common key gestures before they got handled by the TextBox
.您必须处理
PreviewKeyDown
和PreviewKeyUp
事件,以便在它们被TextBox
处理之前捕获常见的按键手势。 TextBox
will handle certain gestures like "Ctrl+C" and then mark the event as handled. TextBox
将处理某些手势,例如“Ctrl+C”,然后将事件标记为已处理。
To print a key combination simply use the KeyGesture.GetDisplayStringForCulture
method (see example below).要打印组合键,只需使用
KeyGesture.GetDisplayStringForCulture
方法(参见下面的示例)。
To register a handler for the recorded gesture, simply define new KeyBinding
and add it to the appropriate UIElement.InputBindings
collection.要为录制的手势注册处理程序,只需定义新的
KeyBinding
并将其添加到适当的UIElement.InputBindings
集合中。 But to make sense, you would have to let the user select the key command (action) first.但要有意义,您必须先让用户 select 键入命令(操作)。 Otherwise you don't know to which action the gesture should map to.
否则你不知道手势应该 map 到哪个动作。
The following example assumes that the selected action is already stored in the SelectedGestureCommand
property.以下示例假定所选操作已存储在
SelectedGestureCommand
属性中。
To handle/override globally registered key gestures like your mentioned "Windows+G", you would have to use P/Invoke to handle those events on OS level.要处理/覆盖全局注册的按键手势,如您提到的“Windows+G”,您必须使用 P/Invoke 在操作系统级别处理这些事件。 There is no WPF API for this task.
此任务没有 WPF API。
MainWindow.xaml主窗口.xaml
<TextBox PreviewKeyDown="RecordGesture_OnKeyDown"
PreviewKeyUp="PrintRecordedGesture_OnKeyUp" />
MainWindow.xamlcs主窗口.xamlcs
public MainWindow()
{
InitializeComponent();
// Register the predefined gestures that the user can later modify.
// TODO::Define the required commands by implementing ICommand for each
this.InputBindings.Add(new KeyBinding(DoSomethingCommand, Key.A, ModifierKeys.Shift | ModifierKeys.Alt));
}
private void RecordGesture_OnKeyDown(object sender, KeyEventArgs e)
{
var newGesture = new KeyGesture(e.Key, e.KeyboardDevice.Modifiers);
// Update the existing action with the new gesture
KeyBinding selectedKeyBinding = this.InputBindings
.OfType<KeyBinding>()
.First(keyBinding => keyBinding.Command == this.SelectedGestureCommand);
selectedKeyBinding.Gesture = newGesture;
}
private void PrintRecordedGesture_OnKeyUp(object sender, KeyEventArgs e)
{
var currentGesture = new KeyGesture(e.Key, e.KeyboardDevice.Modifiers);
// Print the new gesture
(sender as TextBox).Text = currentGesture.GetDisplayStringForCulture(CultureInfo.CurrentCulture);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.