2010-10-05 27 views
20

有沒有講出全部WPF應用程序反應試圖通過關閉當前聚焦寡婦逃生按鍵的任何直接的方式?手動設置命令和輸入綁定並不是一件很麻煩的事情,但我想知道在所有窗口中重複使用這個XAML是否是最優雅的方法?如何爲項目中的所有WPF窗口分配「關閉逃逸按鍵」行爲?

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

歡迎任何建設性意見!

回答

30

我只能建議,以改善是通過結合一個static命令實例來移除事件處理程序的需要。

注:這個,因爲它需要綁定到KeyBinding屬性的能力只會工作,在.NET 4起。

首先,創建需要一個窗口作爲參數,並調用CloseExecute方法中的命令:

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> 

我不知道這是必然比你的更好的方法,但它在每一個頂部略微意味着少樣板和你沒有需要在每個

+0

可這導致內存泄漏,因爲單身人士有一個'EventHandler'? – Maslow 2016-04-07 13:56:30

+0

它不應該這樣做,因爲我們並不關心'CanExecute'功能,您可以通過讓'CanExecute'始終返回true並用空附件實現替換'CanExecuteChanged'處理程序(例如'public event EventHandler CanExecuteChanged {add {} remove {}}') – 2016-04-07 14:00:14

20

的事件處理程序或者你可以只添加一個按鈕,取消文字和設置IsCancel = True。然後Escape將作爲默認命令關閉。

+1

不總是理想的,但仍然像這個建議。夠簡單。 – 2010-11-05 21:27:54

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

無上述工作對我來說,除了凱的結合。 我修改了他的答案:我加入「btn_close.IsCancel = TRUE;」到構造函數。 SettingsWindow是我的第二個窗口,主窗口是(默認)MainWindow。

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

希望它能幫助,

西蒙 愛NIA

0

另一種可能的方式是使用附加屬性

貝婁是一個要點代碼:

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

1

Window s的ShowDialog()所示,你可以使用:

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

您還可以使用PreviewKeyDown事件

PreviewKeyDown="UserControl_PreviewKeyDown" 

代碼背後叫你關閉命令

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