Como posso atribuir o comportamento 'Fechar na Press de Escape-key' a todos os WPF Windows dentro de um projeto?

StackOverflow https://stackoverflow.com/questions/3863431

Pergunta

Existe alguma maneira direta de dizer a todo o aplicativo WPF para reagir para escapar das prensas de teclas tentando fechar a viúva atualmente focada? Não é um grande incômodo configurar manualmente as ligações de comando e entrada, mas me pergunto se repetir esse XAML em todas as janelas é a abordagem mais elegante?

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

Quaisquer sugestões construtivas são bem -vindas!

Foi útil?

Solução

Tudo o que posso sugerir para melhorar isso é remover a necessidade de um manipulador de eventos, ligando -se a uma instância de comando estático.

Nota: Isso funcionará apenas no .NET 4 em diante, pois requer a capacidade de se ligar ao KeyBinding propriedades.

Primeiro, crie um comando que pega uma janela como um parâmetro e chama Close dentro do Execute método:

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

Então você pode vincular seu KeyBinding para a estática Instance propriedade:

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

Eu não sei se isso é necessariamente Melhor do que sua abordagem, mas significa marginalmente menos caldeira no topo de cada Window e que você não precisa incluir um manipulador de eventos em cada

Outras dicas

Ou você pode simplesmente adicionar um botão com cancelamento como texto e definir IsCancel = True. Em seguida, o Escape funcionará como comando padrão para fechar.

crio RoutedUICommand como abaixo

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

e adicione a ligação de comando no construtor

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

Sobre Windows mostrado com ShowDialog() você pode usar:

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

Você também pode usar o evento de visualizeKeyDown

PreviewKeyDown="UserControl_PreviewKeyDown"

Código por trás da chamada com o comando Fechar

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

Outra maneira possível é usar propriedades anexadas

Bellow é um código GIST:

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

Nenhum dos acima funcionou para mim, exceto os de Kai. Modifiquei a resposta dele: adicionei 'btn_close.iscel = true;' para construtor. SettingSwindow é minha segunda janela e a janela principal é (padrão) 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 que ajude,

Amor de Simon Nia

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top