Как я могу назначить поведение «Закрыть при нажатии клавиши Escape» для всех окон WPF в проекте? - PullRequest
21 голосов
/ 05 октября 2010

Есть ли какой-нибудь простой способ заставить целое приложение WPF реагировать на нажатия клавиш Escape, пытаясь закрыть текущую вдову?Ручная настройка привязок команд и ввода не является большой проблемой, но мне интересно, если повторение этого XAML во всех окнах является наиболее элегантным подходом?

Ответы [ 7 ]

32 голосов
/ 02 ноября 2010

Все, что я могу предложить для улучшения, это устранить необходимость в обработчике событий путем привязки к экземпляру статической команды.

Примечание. Это будет работать только в .NET 4 и более поздних версиях, поскольку для этого требуется возможность привязки к свойствам KeyBinding.

Сначала создайте команду, которая принимает Window в качестве параметра и вызывает 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();
}

Затем вы можете привязать свой KeyBinding к статическому Instance свойству:

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

Я не знаю, что это обязательно лучше , чем ваш подход, но это означает незначительное уменьшение шаблонного числа в верхней части каждого Window и что вам не нужно включать обработчик событий в каждом

20 голосов
/ 05 ноября 2010

Или вы можете просто добавить кнопку с Cancel в качестве текста и установить IsCancel = True. Тогда Escape будет работать как команда по умолчанию для закрытия.

3 голосов
/ 08 ноября 2013

создать 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(); }));
1 голос
/ 26 июля 2017

Вы также можете использовать PreviewKeyDown Event

PreviewKeyDown="UserControl_PreviewKeyDown"

Код, стоящий за вызовом команды закрытия

private void UserControl_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                _vm.OnCloseCommand(sender);
            }
        }
1 голос
/ 12 сентября 2016

На Window s показано с ShowDialog(), вы можете использовать:

<!-- Button to close on Esc -->
<Button IsCancel="True" Width="0" Height="0"/>
0 голосов
/ 03 сентября 2015

Другой возможный способ - использовать прикрепленные свойства

Ниже приведен код гистограммы:

<script src="https://gist.github.com/meziantou/1e98d7d7aa6aa859d916.js"></script>
0 голосов
/ 30 января 2015

Ничто из вышеперечисленного не сработало для меня, кроме Кая.Я изменил его ответ: я добавил '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();
    }
  }

Надеюсь, это поможет,

Simon S love nia

...