2010-10-05 14 views
20

Có cách nào đơn giản để nói cho toàn bộ ứng dụng WPF phản ứng với các phím bấm thoát bằng cách cố gắng đóng góa phụ hiện đang tập trung không? Nó không phải là một bận tâm lớn để tự thiết lập các ràng buộc lệnh và đầu vào nhưng tôi tự hỏi nếu lặp đi lặp lại XAML này trong tất cả các cửa sổ là cách tiếp cận thanh lịch nhất?Làm cách nào để chỉ định hành vi 'Đóng khi nhấn phím Escape' cho tất cả các cửa sổ WPF trong một dự án?

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

Bất kỳ đề xuất xây dựng nào đều được chào đón!

Trả lời

30

Tất cả những gì tôi có thể đề xuất để cải thiện đó là loại bỏ nhu cầu về trình xử lý sự kiện bằng cách liên kết với một cá thể lệnh tĩnh.

Lưu ý: thao tác này sẽ chỉ hoạt động trong .NET 4 trở đi vì nó yêu cầu khả năng liên kết với thuộc tính KeyBinding.

Đầu tiên, tạo một lệnh mà phải mất một cửa sổ như một tham số và gọi Close trong Execute phương pháp:

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

Sau đó, bạn có thể kết bạn KeyBinding đến tĩnh Instance tài sản:

<Window.InputBindings> 
    <KeyBinding Key="Escape" Command="{x:Static local:CloseThisWindowCommand.Instance}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" /> 
</Window.InputBindings> 

Tôi không biết rằng điều này nhất thiết phải là tốt hơn so với cách tiếp cận của bạn, nhưng điều đó có nghĩa là bản mẫu hơi ít ở đầu mỗi Window và bạn không cần bao gồm trình xử lý sự kiện trong mỗi

+0

có thể điều này dẫn đến rò rỉ bộ nhớ vì singleton có 'EventHandler'? – Maslow

+0

Nó không nên làm nhưng vì chúng ta không thực sự quan tâm đến chức năng 'CanExecute' mà bạn có thể bảo vệ chống lại nó bằng cách có' CanExecute' luôn trả về true và thay thế trình xử lý 'CanExecuteChanged' bằng các cài đặt đính kèm rỗng (ví dụ' EventHandler CanExecuteChanged {add {} remove {}} ') –

20

Hoặc bạn chỉ có thể thêm nút có Hủy làm văn bản và đặt IsCancel = True. Sau đó, Escape sẽ hoạt động như lệnh mặc định để đóng.

+1

không phải lúc nào cũng lý tưởng nhưng vẫn như gợi ý. Đủ đơn giản. –

2

tạo RoutedUICommand như dưới đây

private static RoutedUICommand EscUICommand = new RoutedUICommand("EscBtnCommand" 
     , "EscBtnCommand" 
     , typeof(WindowName) 
     , new InputGestureCollection(new InputGesture[] 
      { new KeyGesture(Key.Escape, ModifierKeys.None, "Close") })); 

và thêm nó lệnh ràng buộc trong constructor

CommandBindings.Add(new CommandBinding(EscUICommand, (sender, e) => { this.Hide(); })); 
-1

Không ai trong số trên làm việc cho tôi, ngoại trừ Kai. Tôi đã sửa đổi câu trả lời của mình: Tôi đã thêm 'btn_close.IsCancel = true;' để xây dựng. SettingsWindow là cửa sổ thứ hai của tôi, và cửa sổ chính là (mặc định) MainWindow.

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

Hy vọng nó giúp,

Simon S tình yêu nia

0

Một cách khác có thể là sử dụng tài sản gắn liền

Bellow là một mã ý chính:

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

1

On Window s hiển thị với ShowDialog() bạn có thể sử dụng:

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

Bạn cũng có thể sử dụng PreviewKeyDown Event

PreviewKeyDown="UserControl_PreviewKeyDown" 

Mã đằng sau gọi bạn đóng lệnh

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