簡體   English   中英

WPF 確定文本框中釋放的所有鍵?

[英]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;
        }
    }
}

您必須處理PreviewKeyDownPreviewKeyUp事件,以便在它們被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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM