WPF窗口如何处理“Esc”键?

6
我希望按下Escape键可以关闭我的WPF窗口。但是如果有一个控件可以使用该Escape键,则不希望关闭窗口。有多种解决方案可用于在按下ESC键时关闭WPF窗口。例如:WPF Button.IsCancel属性如何工作? 然而,这个解决方案会关闭窗口,而不考虑是否有一个活动控件可以使用Escape键。
例如,我有一个带有DataGrid的窗口。数据网格中的一列是组合框。如果我正在更改ComboBox,并按下Escape键,则控件应该退出ComboBox的编辑(正常行为)。如果我再次按下Escape键,则窗口应该关闭。我想要一个通用的解决方案,而不是编写大量的自定义代码。
如果您能提供C#的解决方案,那将非常好。
3个回答

5
你应该使用KeyDown事件而不是PreviewKeyDown事件。如果Window的任何子元素处理了该事件,则它不会向上冒泡到WindowPreviewKeyDownWindow向下隧道传输),因此你的事件处理程序将不会被调用。

这对我有效。但并非所有情况都是如此。特别是,我正在使用Telerik的DataGrid控件。如果单元格有一个组合框,并且它已经展开,然后我按Escape键,那么Escape键不会传播到窗口。但是,如果ComboBox没有展开,而是处于编辑模式,则Escape键会传播。我认为这可能是控件的一个错误。您的建议确实起作用。 - Markus2k

1
class Commands
{
    static Command
    {
        CloseWindow = NewCommand("Close Window", "CloseWindow", new KeyGesture(Key.Escape));
        CloseWindowDefaultBinding = new CommandBinding(CloseWindow,
            CloseWindowExecute, CloseWindowCanExecute);
    }

    public static CommandBinding CloseWindowDefaultBinding { get; private set; }
    public static RoutedUICommand CloseWindow { get; private set; }

    static void CloseWindowCanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = sender != null && sender is System.Windows.Window;
        e.Handled = true;
    }
    static void CloseWindowExecute(object sender, ExecutedRoutedEventArgs e)
    {
         ((System.Windows.Window)sender).Close();
    }
}

// In your window class's constructor. This could also be done
// as a static resource in the window's XAML resources.
CommandBindings.Add(Commands.CloseWindowDefaultBinding);

1

可能有更简单的方法,但您可以使用哈希码来完成。Keys.Escape是另一种选择,但有时出于某些原因我无法让它起作用。您没有指定语言,因此这里提供一个VB.NET的示例:

Private Sub someTextField_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles someTextField.KeyPress

    If e.KeyChar.GetHashCode = 1769499 Then ''this number is the hash code for escape on my computer, do not know if it is the same for all computers though.
        MsgBox("escape pressed") ''put some logic in here that determines what ever you wanted to know about your "active control"
    End If

End Sub

谢谢回复。我感兴趣的语言是C#。我正在寻找一个通用的解决方案来解决这个问题。我不想为每个控件编写特定的代码。 - Markus2k

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接