2009-01-21 62 views
5

据我所知,命令模式的目标是帮助将UI交互与应用程序逻辑分开。有了正确执行命令,在“打印”菜单项,点击可能会导致这样的互动链条:WPF路由命令是解决问题还是让问题变得更糟?

(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元素与Paste命令关联起来,我只需要使用一个事件处理程序,但是如果我想要粘贴到多个不同的文本框呢?我必须让事件处理程序的逻辑更加复杂或者编写更多的事件处理程序。所以现在,我觉得我有这个:

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

我在这里失踪了什么?它看起来像一个额外的间接层我。

回答

2

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

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

+0

我昨天晚上看了一本关于命令的书,发现了这些信息,然后很快感觉就像是一种涂料。 – OwenP 2009-01-22 16:17:01

0

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

3

你可能会混淆概念。

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

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

2

在构建控件时,我倾向于使用RoutedCommands和RoutedUICommands。例如TextBox为您实现UndoCommand,并且输入偏好已经绑定到Ctrl + Z。 但是,在构建View Models时,我的首选是使用内部实现Execute和CanExecute的自定义ICommand。 DelegateCommand在Prism中提供了这个功能。这允许view/xaml设计器只担心命令而不是正确的Execute/CanExecute处理程序使用。这将允许更具表现力的视图模型。

ps。使用InputBindings代理命令还没有工作(优雅地)。请问微软有人可以修复这个问题!