2010-10-05 21 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); 
      } 
     }