2009-01-21 57 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代理命令還沒有工作(優雅地)。請問微軟有人可以修復這個問題!