wpf escaping command key-bindings windows-applications

¿Cómo puedo asignar el comportamiento ''Cerrar al presionar la tecla Escape'' a todas las ventanas de WPF dentro de un proyecto?



escaping command (7)

En la Window muestra con ShowDialog() puede usar:

<!-- Button to close on Esc --> <Button IsCancel="True" Width="0" Height="0"/>

¿Hay alguna forma sencilla de decirle a toda la aplicación WPF que reaccione a las pulsaciones de la tecla Escape al intentar cerrar la viuda enfocada actualmente? No es una gran molestia configurar manualmente los comandos y los enlaces de entrada, pero me pregunto si repetir el XAML en todas las ventanas es el enfoque más elegante.

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

Cualquier sugerencia constructiva bienvenida!


Nada de lo anterior funcionó para mí, excepto el de Kai. Modifiqué su respuesta: agregué ''btn_close.IsCancel = true;'' al constructor. SettingsWindow es mi segunda ventana, y la ventana principal es (predeterminada) MainWindow.

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

Espero eso ayude,

Simon s amor nia


O simplemente puede agregar un botón con Cancelar como texto y establecer IsCancel = True . Entonces Escape funcionará como comando predeterminado para cerrar.


Otra forma posible es utilizar propiedades adjuntas.

Bellow es un código esencial:

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


También puedes usar el evento PreviewKeyDown

PreviewKeyDown="UserControl_PreviewKeyDown"

Código detrás de llamarte comando de cierre

private void UserControl_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) { if (e.Key == Key.Escape) { _vm.OnCloseCommand(sender); } }


Todo lo que puedo sugerir para mejorar eso es eliminar la necesidad de un controlador de eventos enlazando a una instancia de comando estática.

Nota: esto solo funcionará en .NET 4 en adelante ya que requiere la capacidad de enlazar a las propiedades de KeyBinding .

Primero, cree un comando que tome una ventana como parámetro y llame a Close dentro del método 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(); }

Luego puedes vincular tu KeyBinding a la propiedad de Instance estática:

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

No sé que esto sea necesariamente mejor que su enfoque, pero significa un poco menos de repetición en la parte superior de cada Window y que no es necesario incluir un controlador de eventos en cada


crear RoutedUICommand como abajo

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

y agregarlo comando de enlace en el constructor

CommandBindings.Add(new CommandBinding(EscUICommand, (sender, e) => { this.Hide(); }));