5

据我了解,命令模式的目标是帮助将 UI 交互与应用程序逻辑分开。使用正确实现的命令,单击“打印”菜单项可能会导致如下交互链:

(button) ---click executes command----> (command) ---calls Print() in app logic ---> (logic)

这鼓励您将 UI 与应用程序逻辑分开。

我一直在研究 WPF 命令,并且在大多数情况下,我看到了它们是如何实现这种模式的。然而,我觉得在某种程度上他们已经复杂化了命令模式并设法以这样一种方式实现它,以至于你不鼓励将 UI 与应用程序逻辑分离。

例如,考虑这个简单的 WPF 窗口,它有一个用于将文本粘贴到文本框中的按钮:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Paste"
                        Executed="CommandBinding_Executed"/>
    </Window.CommandBindings>
    <StackPanel>
        <TextBox x:Name="txtData" />
        <Button Command="Paste" Content="Paste" />
    </StackPanel>
</Window>

这是代码隐藏:

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ApplicationCommands.Paste.Execute(null, txtData);
        }
    }
} 

我从命令中得到了什么?在我看来,我可以很容易地将命令绑定事件处理程序中的代码放入按钮的Click事件中。当然,现在我可以将多个 UI 元素与粘贴命令相关联,并且只需要使用一个事件处理程序,但是如果我想粘贴到多个不同的文本框怎么办?我必须使事件处理程序逻辑更复杂或编写更多事件处理程序。所以现在,我觉得我有这个:

(button) ---executes Routed Command---> (Window) ---executes command binding----(command binding)
(logic) <---calls application logic--- (event handler) <-----raises event --------------|

我在这里想念什么?对我来说,它看起来像是额外的间接层。

4

4 回答 4

3

你可能会混淆概念。

ICommand接口支持命令模式。这允许您将用户操作抽象为可重用的类。

ICommand路由命令是通过可视化树搜索处理程序的特定实现。它们对于可以由许多不同控件实现的命令特别有用,并且您希望当前控件处理它。想想复制/粘贴。可能有一大堆控件可以处理它,但是通过使用路由命令,路由命令系统将根据焦点自动找到正确的控件来处理命令。

于 2009-01-21T19:59:42.800 回答
2

除了已经提到的内容之外,您在特定的粘贴示例中忘记了 CommandTarget 和 CommandParameter 属性。对于粘贴,您可以通过设置为 CommandTarget 来指定文本框。

当想要从不同的控件使用相同的 RoutedCommand 时,这些属性是绝对必要的。它们允许您向 Executed 处理程序提供有关调用命令的上下文的一些信息。

于 2009-01-21T22:04:05.857 回答
2

在构建控件时,我倾向于使用 RoutedCommands 和 RoutedUICommands。例如 TextBox 为您实现 UndoCommand 并且 Input guseture 已经绑定到Ctrl+ Z。然而,在构建视图模型时,我更喜欢使用内部实现 Execute 和 CanExecute 的自定义 ICommand。DelegateCommand 在 Prism 中提供此功能。这允许 view/xaml 设计者只关心命令而不是正确的 Execute/CanExecute 处理程序使用。这将允许更具表现力的视图模型。

附言。委托命令还不能(优雅地)与 InputBindings 一起工作。请微软的某个人解决这个问题!

于 2009-01-22T10:18:12.537 回答
0

它们在某些事情上可能有点矫枉过正,但你确实得到了一些不错的好处,比如 CanExecute 可以在命令不可用时自动启用/禁用按钮/菜单项(例如未选择文本等)。您还可以在 Blend 中执行命令操作,而无需使用任何代码,这对设计师来说非常有用。

于 2009-01-21T19:52:23.783 回答