web-dev-qa-db-ja.com

プロジェクト内のすべてのWPFウィンドウに「エスケープキーを押して閉じる」動作を割り当てるにはどうすればよいですか?

現在フォーカスされている未亡人を閉じようとして、Escキーの押下に反応するようにWPFアプリケーション全体に指示する簡単な方法はありますか?コマンドバインディングと入力バインディングを手動で設定するのはそれほど面倒ではありませんが、すべてのウィンドウでこのXAMLを繰り返すことが最も洗練されたアプローチであるかどうか疑問に思います。

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

建設的な提案は大歓迎です!

22
Peter Perháč

それを改善するために提案できるのは、静的コマンドインスタンスにバインドすることでイベントハンドラーの必要性をなくすことだけです。

注:これは、KeyBindingプロパティにバインドする機能を必要とするため、.NET4以降でのみ機能します。

まず、ウィンドウをパラメーターとして受け取り、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の上部にある定型文がわずかに少なく、イベントを含める必要がないことを意味しますそれぞれのハンドラー

32
Steve Greatrex

または、[キャンセル]をテキストとして使用するボタンを追加し、IsCancel = Trueを設定することもできます。その後、Escapeは閉じるためのデフォルトコマンドとして機能します。

21
Kai

以下のように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(); }));
2
Mahi

PreviewKeyDownイベントを使用することもできます

PreviewKeyDown="UserControl_PreviewKeyDown"

Call youcloseコマンドの背後にあるコード

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

ShowDialog()で示されるWindowsでは、以下を使用できます。

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

別の可能な方法は、添付プロパティを使用することです

ベローは要点コードです:

<script src="https://Gist.github.com/meziantou/1e98d7d7aa6aa859d916.js"></script>
0
Rui Sebastião