[英]WPF determine all keys released in textbox?
我想讓用戶自定義快捷鍵,所以我使用文本框來獲取鍵輸入。 預期的 state 應該是在按下時保存鍵,並在釋放時顯示 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;
}
}
如何達到正確的效果?
編輯:誤解了這個問題,這是針對已經記錄了快捷方式的情況。
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;
}
}
}
您必須處理PreviewKeyDown
和PreviewKeyUp
事件,以便在它們被TextBox
處理之前捕獲常見的按鍵手勢。 TextBox
將處理某些手勢,例如“Ctrl+C”,然后將事件標記為已處理。
要打印組合鍵,只需使用KeyGesture.GetDisplayStringForCulture
方法(參見下面的示例)。
要為錄制的手勢注冊處理程序,只需定義新的KeyBinding
並將其添加到適當的UIElement.InputBindings
集合中。 但要有意義,您必須先讓用戶 select 鍵入命令(操作)。 否則你不知道手勢應該 map 到哪個動作。
以下示例假定所選操作已存儲在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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.