WPF确定文本框中释放的所有密钥



我想让用户自定义快捷键,所以我使用文本框来获取键输入。预期状态应该是按下时保存键,释放时显示KeyGesture字符串。

但有些键将由其他注册的热键(如Ctrl+A、win+G等(响应,无法确定这些键是否全部释放,因此无法在适当的时候清除ModifierKeys。

这是我的代码,如果输入一个注册的热键,这个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;
}
}

如何实现正确的效果?

TextBox处理PreviewKeyDownPreviewKeyUp事件之前,必须先处理它们以捕获常见的按键手势。CCD_ 4将处理某些手势;Ctrl+C";然后将该事件标记为已处理。

要打印密钥组合,只需使用KeyGesture.GetDisplayStringForCulture方法(参见下面的示例(
要为录制的手势注册处理程序,只需定义新的KeyBinding并将其添加到相应的UIElement.InputBindings集合中。但要想有意义,您必须让用户首先选择键命令(操作(。否则,您不知道手势应该映射到哪个动作。
以下示例假设所选动作已存储在SelectedGestureCommand属性中。

为了处理/覆盖全局注册的按键手势;Windows+G";,您必须使用P/Invoke在操作系统级别上处理这些事件。此任务没有WPF API。

主窗口.xaml

<TextBox PreviewKeyDown="RecordGesture_OnKeyDown"
PreviewKeyUp="PrintRecordedGesture_OnKeyUp" />

主窗口.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);
}

EDIT:误解了这个问题,这是因为快捷方式已经录制好了。

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;
}
}
}

最新更新