2008-08-12 43 views
34

Tôi đã thực hiện một số chương trình WPF và một điều tôi chưa bao giờ có là mẫu lệnh. Mỗi ví dụ dường như được xây dựng trong những người thân, chỉnh sửa, cắt, dán. Bất cứ ai có một ví dụ hoặc đề nghị thực hành tốt nhất cho các lệnh tùy chỉnh?Ví dụ mẫu lệnh WPF tùy chỉnh

Trả lời

38

Ah ha! Một câu hỏi tôi có thể trả lời! Thứ nhất, tôi nên đề cập đến rằng tôi đã cá nhân tìm thấy nó dễ dàng hơn để xác định và treo lên các lệnh trong mã hơn là trong XAML. Nó cho phép tôi kết nối các trình xử lý cho các lệnh một cách linh hoạt hơn một cách tiếp cận XAML tất cả.

Bạn nên tìm ra những lệnh bạn muốn có và những gì chúng liên quan đến. Trong ứng dụng của tôi, tôi hiện đang có một lớp để xác định các lệnh ứng dụng quan trọng như vậy:

public static class CommandBank 
{ 
    /// Command definition for Closing a window 
    public static RoutedUICommand CloseWindow { get; private set; } 

    /// Static private constructor, sets up all application wide commands. 
    static CommandBank() 
    { 
    CloseWindow = new RoutedUICommand(); 
    CloseWindow.InputGestures.Add(new KeyGesture(Key.F4, ModifierKeys.Alt)); 
    // ... 
    } 

Bây giờ, vì tôi muốn giữ mã tất cả lại với nhau, sử dụng một mã số duy nhất cách tiếp cận để lệnh cho phép tôi đặt các phương pháp sau đây trong lớp học ở trên:

/// Closes the window provided as a parameter 
public static void CloseWindowExecute(object sender, ExecutedRoutedEventArgs e) 
{ 
    ((Window)e.Parameter).Close(); 
} 

/// Allows a Command to execute if the CommandParameter is not a null value 
public static void CanExecuteIfParameterIsNotNull(object sender, CanExecuteRoutedEventArgs e) 
{ 
    e.CanExecute = e.Parameter != null; 
    e.Handled = true; 
} 

Phương pháp thứ hai thậm chí có thể được chia sẻ với các Lệnh khác mà không cần phải lặp lại tất cả mọi nơi.

Khi bạn đã xác định các lệnh như thế này, bạn có thể thêm chúng vào bất kỳ phần giao diện người dùng nào. Trong phần sau, khi Window đã được nạp, tôi thêm các ràng buộc lệnh vào cả Window và MenuItem và sau đó thêm một ràng buộc đầu vào vào Window bằng cách sử dụng một vòng lặp để thực hiện điều này cho tất cả các ràng buộc lệnh. Các tham số được thông qua là cửa sổ tự của nó để mã trên biết những gì Window để thử và đóng.

public partial class SimpleWindow : Window 
{ 
    private void WindowLoaded(object sender, RoutedEventArgs e) 
    { 
    // ... 
    this.CommandBindings.Add(
     new CommandBinding(
     CommandBank.CloseWindow, 
     CommandBank.CloseWindowExecute, 
     CommandBank.CanExecuteIfParameterIsNotNull)); 

    foreach (CommandBinding binding in this.CommandBindings) 
    { 
     RoutedCommand command = (RoutedCommand)binding.Command; 
     if (command.InputGestures.Count > 0) 
     { 
     foreach (InputGesture gesture in command.InputGestures) 
     { 
      var iBind = new InputBinding(command, gesture); 
      iBind.CommandParameter = this; 
      this.InputBindings.Add(iBind); 
     } 
     } 
    } 

    // menuItemExit is defined in XAML 
    menuItemExit.Command = CommandBank.CloseWindow; 
    menuItemExit.CommandParameter = this; 
    // ... 
    } 

    // .... 
} 

Sau đó, tôi cũng có trình xử lý sự kiện cho các sự kiện WindowClosing và WindowClosed, tôi khuyên bạn nên triển khai thực hiện các lệnh nhỏ và chung nhất có thể. Như trong trường hợp này, tôi đã không cố gắng để đặt mã mà cố gắng để ngăn chặn các cửa sổ đóng cửa nếu có dữ liệu chưa lưu, tôi giữ mã đó vững chắc bên trong sự kiện WindowClosing.

Hãy cho tôi biết nếu bạn có bất kỳ câu hỏi nào tiếp theo. :)

+2

CanExecuteIfParameterIsNotNull của bạn có chứa một trong những phiền toái vật cưng của tôi. Tại sao không chỉ e.CanExecute = e.Parameter! = Null; – Ray

+0

@Ray Đó không phải là điều tôi biết tôi có thể làm! Cảm ơn bạn đã chỉnh sửa Drew. :) – Nidonocu

3

Điều về XAML là nó là tốt cho các chương trình 'đơn giản', nhưng thật đáng buồn, nó không hoạt động tốt khi bạn muốn làm những việc như chức năng chia sẻ. Giả sử bạn có một số lớp và giao diện người dùng của tất cả đều có các lệnh chưa từng bị vô hiệu hóa, bạn phải viết phương thức 'CanAlwaysExecute' cho mỗi Window hoặc UserControl! Đó không chỉ là DRY.

Đã đọc một số blog và thông qua việc thử một số thứ, tôi đã thực hiện lựa chọn để làm cho XAML hoàn toàn về ngoại hình, kiểu, hoạt ảnh và trình kích hoạt. Tất cả sự sắp xếp của tôi về các trình xử lý sự kiện và chỉ huy bây giờ đều nằm trong đoạn mã phía sau. :)

Một dấu khác bằng cách này là Ràng buộc đầu vào, để chúng bị bắt, tiêu điểm phải nằm trên đối tượng có chứa các ràng buộc đầu vào. Ví dụ, để cắt ngắn, bạn có thể sử dụng bất kỳ lúc nào (ví dụ, F1 để mở trợ giúp), ràng buộc đầu vào phải được đặt trên đối tượng Window, vì luôn có tiêu điểm khi ứng dụng của bạn đang hoạt động. Sử dụng phương pháp mã nên làm cho dễ dàng hơn, ngay cả khi bạn bắt đầu sử dụng UserControls có thể muốn thêm các ràng buộc đầu vào vào cửa sổ cha mẹ của chúng.

7
+2

http://blogs.vertigo.com/personal/alanl/Blog/archive/2007/05/31/commands-in-wpf.aspx liên kết này đã chết: ( – Drahakar

Các vấn đề liên quan