23

是否有任何直接的方法可以通过尝试关闭当前聚焦的寡妇来告诉整个 WPF 应用程序对 Escape 按键做出反应?手动设置命令和输入绑定并不是一件很麻烦的事,但我想知道在所有窗口中重复这个 XAML 是否是最优雅的方法?

<Window.CommandBindings>
        <CommandBinding Command="Close" Executed="CommandBinding_Executed" />
</Window.CommandBindings>
<Window.InputBindings>
        <KeyBinding Key="Escape" Command="Close" />
</Window.InputBindings>

欢迎任何建设性的建议!

4

8 回答 8

33

我可以建议改进的是通过绑定到静态命令实例来消除对事件处理程序的需求。

注意:这仅适用于 .NET 4 及更高版本,因为它需要绑定到KeyBinding属性的能力。

首先,创建一个以 Window 作为参数并CloseExecute方法内调用的命令:

public class CloseThisWindowCommand : ICommand
{
    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        //we can only close Windows
        return (parameter is Window);
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        if (this.CanExecute(parameter))
        {
            ((Window)parameter).Close();
        }
    }

    #endregion

    private CloseThisWindowCommand()
    {

    }

    public static readonly ICommand Instance = new CloseThisWindowCommand();
}

然后你可以将你的绑定KeyBinding到静态Instance属性:

<Window.InputBindings>
    <KeyBinding Key="Escape" Command="{x:Static local:CloseThisWindowCommand.Instance}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" />
</Window.InputBindings>

我不知道这一定比您的方法更好,但这确实意味着每个顶部的样板要少一些,Window并且您不需要在每个中包含事件处理程序

于 2010-11-02T17:04:05.190 回答
22

Or you could just add a button with Cancel as text and set IsCancel = True. Then Escape will work as default command to close.

于 2010-11-05T20:54:23.237 回答
2

创建RoutedUICommand如下

 private static RoutedUICommand EscUICommand = new RoutedUICommand("EscBtnCommand"
       , "EscBtnCommand"
       , typeof(WindowName)
       , new InputGestureCollection(new InputGesture[] 
           { new KeyGesture(Key.Escape, ModifierKeys.None, "Close") }));

并在构造函数中添加它的命令绑定

CommandBindings.Add(new CommandBinding(EscUICommand, (sender, e) => { this.Hide(); }));
于 2013-11-08T07:17:30.400 回答
1

另一种可能的方法是使用附加属性

贝娄是一个要点代码:

<script src="https://gist.github.com/meziantou/1e98d7d7aa6aa859d916.js"></script>

于 2015-09-03T10:28:29.633 回答
1

您还可以使用 PreviewKeyDown 事件

PreviewKeyDown="UserControl_PreviewKeyDown"

后面的代码叫你关闭命令

private void UserControl_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                _vm.OnCloseCommand(sender);
            }
        }
于 2017-07-26T12:45:01.917 回答
1

Window显示的 s 上,ShowDialog()您可以使用:

<!-- Button to close on Esc -->
<Button IsCancel="True" Width="0" Height="0"/>
于 2016-09-12T02:22:46.770 回答
0

事件Preview发生得相当早。如果您有一个控件应该Esc为自己的目的获取密钥,那么在窗口级别窃取它可能过于激进。

相反,只有在没有其他需要时,您才能处理它:

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);

    if (!e.Handled && e.Key == Key.Escape && Keyboard.Modifiers == ModifierKeys.None)
    {
        this.Close();
    }
}
于 2021-03-30T04:06:03.460 回答
-1

以上都不适合我,除了凯。我修改了他的答案:我添加了 'btn_close.IsCancel = true;' 给构造函数。SettingsWindow 是我的第二个窗口,主窗口是(默认)MainWindow。

  public partial class SettingsWindow : Window {
    public SettingsWindow() {
      InitializeComponent();
      btn_close.IsCancel = true;
    }
    private void btn_close_Click(object sender, RoutedEventArgs e) {
      this.Close();
    }
  }

希望能帮助到你,

西蒙的爱妮娅

于 2015-01-30T13:59:10.860 回答