23

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

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

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

4

8 に答える 8

33

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

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

まず、ウィンドウをパラメーターとして受け取り、メソッド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、それぞれにイベントハンドラーを含める必要がないことを意味します

于 2010-11-02T17:04:05.190 に答える
22

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

于 2010-11-05T20:54:23.237 に答える
2

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(); }));
于 2013-11-08T07:17:30.400 に答える
1

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

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

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

于 2015-09-03T10:28:29.633 に答える
1

で示さWindowれているShowDialog()場合は、次を使用できます。

<!-- Button to close on Esc -->
<Button IsCancel="True" Width="0" Height="0"/>
于 2016-09-12T02:22:46.770 に答える
1

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

PreviewKeyDown="UserControl_PreviewKeyDown"

コール・ユー・クローズ・コマンドの背後にあるコード

private void UserControl_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                _vm.OnCloseCommand(sender);
            }
        }
于 2017-07-26T12:45:01.917 に答える
0

イベントはPreviewかなり早い段階で発生します。Esc独自の目的でキーを取得する必要があるコントロールがある場合、ウィンドウレベルでキーを盗むのは攻撃的すぎる可能性があります。

代わりに、他に何もしたくない場合にのみ処理できます。

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);

    if (!e.Handled && e.Key == Key.Escape && Keyboard.Modifiers == ModifierKeys.None)
    {
        this.Close();
    }
}
于 2021-03-30T04:06:03.460 に答える
-1

Kaiを除いて、上記のどれも私にはうまくいきませんでした。私は彼の答えを修正しました:「btn_close.IsCancel=true;」を追加しました コンストラクターに。SettingsWindowは私の2番目のウィンドウであり、メインウィンドウは(デフォルト)MainWindowです。

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

それが役に立てば幸い、

サイモンSラブニア

于 2015-01-30T13:59:10.860 に答える