Tất cả các menu/contextmenus/thanh công cụ tôi sử dụng trong WPF được khai báo trong mã ViewModel khá nhiều như thế này:MenuMục tắt bàn phím trong 'MVVM' thuần túy?
MenuService.Add(new MenuItem()
{
Header = "DoStuff",
Command = new relayCommand(DoStuff,() => CanDoStuffExecute())
// some more properties like parent item/image/...
});
Các MenuService cung cấp một điểm ràng buộc duy nhất mà là một danh sách cây của MenuItem và bị ràng buộc để Menu của thực tế ItemsSource in xaml.
Điều này hoạt động rất tốt và bây giờ tôi muốn thêm phím tắt theo cùng một cách thuận tiện. Lý tưởng nhất là MenuItem sẽ nhận được một loại tài sản của System.Windows.Input.KeyGesture
vì vậy tôi chỉ có thể viết
Shortcut = new KeyGesture(Key.D, ModifierKeys.Control)
đó sẽ dẫn đến việc chỉ huy của mặt hàng đó được kêu gọi nhấn Ctrl + D trong cửa sổ sở hữu menu, và đó cũng sẽ dẫn đến tự động hiển thị "Ctrl + D" trong menu.
Tuy nhiên tôi bị mất ở đây: Tôi muốn thiết lập bộ sưu tập MenuItem.InputBindings thông qua dữ liệu nhưng nó chỉ có được. Làm thế nào tôi có thể nhận được các mục vào nó? Hoặc là có một khuôn khổ MVVM đã hỗ trợ một cái gì đó như thế này? Hầu hết q & tôi tìm thấy trên các phím tắt là tất cả về cách thiết lập các phím tắt thông qua xaml, đó là không có sự giúp đỡ.
Cập nhật
Tìm kiếm 'relaycommand vs routeduicommand và 'relaycommand keygesture' vv đã tiết lộ đầy đủ thông tin để đưa ra một giải pháp làm việc mặc dù hacky. Chắc chắn có những cách khác và tốt hơn ngoài kia, nhưng hiện tại đây là ưu tiên cực thấp đối với tôi và thực hiện công việc một cách hoàn hảo. Tôi bổ sung thêm hai tính đến lớp MenuItem như thế này:
//Upon setting a Gesture, the original command is replaced with a RoutedCommand
//since that automatically gives us proper display of the keyboard shortcut.
//The RoutedCommand simply calls back into the original Command.
//It also sets the CommandBinding property, which still has to be added to the
//CommandBindingCollection of either the bound control or one of it ancestors
public InputGesture Gesture
{
set
{
var origCmd = Command;
if(origCmd == null)
return;
var routedCmd = new RoutedCommand(Header,
typeof(System.Windows.Controls.MenuItem),
new InputGestureCollection { value });
CommandBinding = new CommandBinding(routedCmd,
(sender, args) => origCmd.Execute(args.Parameter),
(sender, args) => { args.CanExecute = origCmd.CanExecute(args.Parameter); });
Command = routedCmd;
}
}
//CommandBinding created when setting Gesture
public CommandBinding CommandBinding { get; private set; }
Vì vậy, điều này mang lại các chức năng tôi yêu cầu ban đầu (tức là thêm phím tắt trong mã nơi họ có thể dễ dàng cấu hình vv). Tất cả những gì còn lại là đăng ký các lệnh. Tại thời điểm này được thực hiện đơn giản bằng cách thêm tất cả chúng vào Application.Current.MainWindow.CommandBindings.
Bạn có thể cung cấp một số mẫu mã không? Bạn có nghĩa là tôi nên xác định trình đơn hoàn chỉnh trong xaml? Hay chỉ là lối tắt? Tôi muốn xem như thế nào .. Tôi cần những thứ như một trình đơn 'Tools' toàn cầu, trong đó bổ sung có thể thêm menu con theo ý muốn - có thể thậm chí được thực hiện trong xaml? Ngoài ra, nó có thể, nó sẽ loại bỏ mã với xaml, không? Bây giờ tất cả những gì tôi cần để thêm một lệnh menu là mã như được hiển thị. Đó là ngắn và tiện dụng vì nó có thể nhận được và nó hoạt động rất tốt. Btw tường gạch của bạn hoạt động theo 2 hướng: Tôi chưa thấy một ứng dụng quy mô lớn mà không có mảnh UX nào được định nghĩa trong mã .. Đó là một huyền thoại. – stijn
Bạn hoàn toàn đúng - và tôi đã nhìn thấy một số dự án WPF UX khá lớn đã cố gắng thực sự khó khăn để tránh bất kỳ mã nào - và vết thương không cần thiết gây khó chịu. Tôi cố gắng chỉ sử dụng phương pháp tiếp cận nào hoạt động và đơn giản nhất. Đây là đoạn trích mẫu (xin lỗi vì thiếu tiếng tăm - Tôi không chắc chắn cách định dạng trang này trên trang web này) .. '
chỉnh sửa câu trả lời của bạn, dán mã, chọn nó và nhấp vào nút * Mã mẫu * .. – stijn