Como posso atribuir o comportamento 'Fechar na Press de Escape-key' a todos os WPF Windows dentro de um projeto?
-
27-09-2019 - |
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!
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 Window
s 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