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
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. :)
Đ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.
Tôi viết blog về một loạt các nguồn tài nguyên trên WPF lệnh cùng với một ví dụ năm ngoái tại http://blogs.vertigo.com/personal/alanl/Blog/archive/2007/05/31/commands-in-wpf.aspx
dán ở đây:
Adam Nathan’s sample chapter on Important New Concepts in WPF: Commands
MSDN article: The Command Pattern In WPF
Keyvan Nayyeri: How to Add Commands to Custom WPF Control
Ian Griffiths: Avalon Input, Commands, and Handlers
MSDN Library: Commanding Overview
MSDN Library: CommandBinding Class
MSDN Library: Input and Commands How-to Topics
MSDN Library: EditingCommands Class
MSDN Library: MediaCommands Class
MSDN Library: ApplicationCommands Class
MSDN Library: NavigationCommands Class
MSDN Library: ComponentCommands Class
Cũng chôn trong các mẫu WPF SDK, có một mẫu đẹp trên chỉnh sửa RichTextBox mà tôi đã mở rộng. Bạn có thể tìm thấy tại đây: RichTextEditor.zip
http://blogs.vertigo.com/personal/alanl/Blog/archive/2007/05/31/commands-in-wpf.aspx liên kết này đã chết: ( – Drahakar
Trong ấn bản tháng 9 năm 2008 của tạp chí MSDN, Brian Noyes có một bài viết tuyệt vời về RoutedCommand/RoutedEvents !!!
Dưới đây là liên kết: http://msdn.microsoft.com/en-us/magazine/cc785480.aspx
Liên kết đã chết ... – ardila
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
@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