我已经完成了一些 WPF 编程,但我从未得到过命令模式。每个示例似乎都是内置的、编辑、剪切、粘贴。有人有自定义命令最佳实践的示例或建议吗?

有帮助吗?

解决方案

啊哈!一个我能回答的问题!首先,我应该提到,我个人发现在代码中定义和连接命令比在 XAML 中更容易。它允许我比全 XAML 方法更灵活地连接命令处理程序。

您应该弄清楚您想要什么命令以及它们与什么相关。在我的应用程序中,我目前有一个用于定义重要应用程序命令的类,如下所示:

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));
    // ...
  }

现在,因为我想将代码全部保留在一起,所以使用仅代码方法来处理命令可以让我将以下方法放在上面的类中:

/// 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;
}

第二种方法甚至可以与其他命令共享,而无需我到处重复。

一旦定义了这样的命令,您就可以将它们添加到 UI 的任何部分。在下面,加载窗口后,我将命令绑定添加到 Window 和 MenuItem,然后使用循环将输入绑定添加到 Window,为所有命令绑定执行此操作。传递的参数是窗口本身,因此上面的代码知道要尝试并关闭哪个窗口。

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;
    // ...
  }

  // ....
}

后来我也有 WindowClosing 和 WindowClosed 事件的事件处理程序,我建议您使命令的实际实现尽可能小和通用。在本例中,我没有尝试放置在有未保存数据的情况下尝试阻止窗口关闭的代码,而是将该代码牢固地保留在 WindowClosing 事件中。

如果您有任何后续问题,请告诉我。:)

其他提示

在 2008 年 9 月版的 MSDN 杂志中,Brian Noyes 有一篇关于 RoutedCommand/RoatedEvents 的精彩文章!!!

链接在这里:http://msdn.microsoft.com/en-us/magazine/cc785480.aspx

关于 XAML 的问题是,它对于“简单”程序来说很好,但遗憾的是,当您想要执行共享函数之类的操作时,它就不能很好地工作。假设您有多个类和 UI,所有这些类和 UI 都具有从未禁用的命令,您必须为每个 Window 或 UserControl 编写一个“CanAlwaysExecute”方法!这只是不太 干燥.

阅读了几篇博客并尝试了一些事情后,我决定让 XAML 纯粹关于外观、样式、动画和触发器。我所有的事件处理程序和命令的连接现在都在代码隐藏中。:)

顺便说一句,另一个问题是输入绑定,为了捕获它们,焦点必须放在包含输入绑定的对象上。例如,要拥有可以随时使用的快捷方式(例如,F1 打开帮助),必须在 Window 对象上设置输入绑定,因为当您的应用程序处于活动状态时,该输入绑定始终具有焦点。即使您开始使用可能想要将输入绑定添加到其父窗口的 UserControls,使用代码方法也应该使这变得更容易。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top