代码之家  ›  专栏  ›  技术社区  ›  Peter Perháč

如何将“按Escape键时关闭”行为指定给项目中的所有WPF窗口?

  •  21
  • Peter Perháč  · 技术社区  · 14 年前

    有没有直接的方法告诉整个WPF应用程序通过尝试关闭当前关注的窗口来对逃逸键做出反应?手动设置命令和输入绑定并不麻烦,但我想知道在所有窗口中重复这个XAML是否是最优雅的方法?

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

    欢迎提出建设性意见!

    7 回复  |  直到 14 年前
        1
  •  32
  •   Steve Greatrex    14 年前

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

    注意:这只适用于.NET4以后的版本,因为它需要绑定到 KeyBinding

    首先,创建一个以窗口为参数的命令并调用 Close Execute

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

    键绑定 对静电 Instance 属性:

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

    我不知道这是必要的 更好的 比你的方法,但它确实意味着稍微少一些样板在顶部的每一个 Window

        2
  •  22
  •   CharithJ    7 年前

    或者您可以添加一个按钮,将“取消”作为文本并设置 IsCancel = True . 然后Escape将作为默认的关闭命令。

        3
  •  2
  •   Peter Perháč    11 年前

    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(); }));
    
        4
  •  1
  •   Rui Sebastião    9 年前

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

    <script src="https://gist.github.com/meziantou/1e98d7d7aa6aa859d916.js"></script>
        5
  •  1
  •   markmnl    8 年前

    Window 显示为 ShowDialog()

    <!-- Button to close on Esc -->
    <Button IsCancel="True" Width="0" Height="0"/>
    
        6
  •  1
  •   Mohammad Atiour Islam    7 年前

    也可以使用PreviewKeyDown事件

    PreviewKeyDown="UserControl_PreviewKeyDown"
    

    代码隐藏呼叫关闭命令

    private void UserControl_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
            {
                if (e.Key == Key.Escape)
                {
                    _vm.OnCloseCommand(sender);
                }
            }
    
        7
  •  -1
  •   chistabo    9 年前

    以上这些对我都不管用,除了凯的。

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

    希望有帮助,

    西蒙