How can I assign the 'Close on Escape-key press' behavior to all WPF windows within a project?

后端 未结 7 2179
长发绾君心
长发绾君心 2020-12-25 13:21

Is there any straightforward way of telling the whole WPF application to react to Escape key presses by attempting to close the currently focused widow? It is not a great bo

相关标签:
7条回答
  • 2020-12-25 13:41

    You can also use PreviewKeyDown Event

    PreviewKeyDown="UserControl_PreviewKeyDown"
    

    Code behind call you close command

    private void UserControl_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
            {
                if (e.Key == Key.Escape)
                {
                    _vm.OnCloseCommand(sender);
                }
            }
    
    0 讨论(0)
  • 2020-12-25 13:45

    Another possible way is to use attached properties

    Bellow is a gist code:

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

    0 讨论(0)
  • 2020-12-25 13:50

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

    0 讨论(0)
  • 2020-12-25 13:50

    create RoutedUICommand like below

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

    and add it command binding in constructor

    CommandBindings.Add(new CommandBinding(EscUICommand, (sender, e) => { this.Hide(); }));
    
    0 讨论(0)
  • 2020-12-25 13:57

    All I can suggest to improve on that is to remove the need for an event handler by binding to a static command instance.

    Note: this will only work in .NET 4 onwards as it requires the ability to bind to the KeyBinding properties.

    First, create a command that takes a Window as a parameter and calls Close within the Execute method:

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

    Then you can bind your KeyBinding to the static Instance property:

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

    I don't know that this is necessarily better than your approach, but it does mean marginally less boilerplate at the top of every Window and that you don't need to include an event handler in each

    0 讨论(0)
  • 2020-12-25 13:57

    On Windows shown with ShowDialog() you can use:

    <!-- Button to close on Esc -->
    <Button IsCancel="True" Width="0" Height="0"/>
    
    0 讨论(0)
提交回复
热议问题