Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do WPF Routed Commands solve a problem or make it worse?

From what I understand, the goal of the Command pattern is to help separate UI interaction from application logic. With properly implemented commands, a click on a "Print" menu item might result in a chain of interaction like this:

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

This encourages you to separate the UI from the application logic.

I've been looking at WPF commands, and for the most part I see how they've implemented this pattern. However, I feel like to a certain extent they've complicated the Command pattern and managed to implement it in such a way that you are discouraged from separating the UI from application logic.

For example, consider this simple WPF window that has a button to paste text into the text box:

<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>

Here's the code-behind:

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

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

What did I gain from the command? It seems to me that I could have just as easily put the code from the command binding event handler into the button's Click event. Sure, now I can associate multiple UI elements with the Paste command and I only have to use the one event handler, but what if I want to paste to several different text boxes? I'd have to make the event handler logic more complicated or write more event handlers. So now, I feel like I have this:

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

What am I missing here? It looks like an extra layer of indirection to me.

like image 297
OwenP Avatar asked Jan 21 '09 19:01

OwenP


People also ask

Why would you want to use routed commands instead of events?

Routed commands give you three main things on top of normal event handling: Routed command source elements (invokers) can be decoupled from command targets (handlers)—they do not need direct references to one another, as they would if they were linked by an event handler.

What is WPF command?

Commanding is an input mechanism in Windows Presentation Foundation (WPF) which provides input handling at a more semantic level than device input. Examples of commands are the Copy, Cut, and Paste operations found on many applications.


2 Answers

You may be confusing concepts.

The ICommand interface supports the command pattern. That allows you to abstract user actions into a re-usable class.

Routed commands are a particular implementation of ICommand that search through the visual tree for handlers. They are particularly useful for commands that can be implemented by many different controls, and you want the current control to handle it. Think copy/paste. There could be a whole bunch of controls that might handle it, but by using the routed command, the routed command system will automatically find the correct control to handle the command based on focus.

like image 167
Kent Boogaart Avatar answered Sep 24 '22 02:09

Kent Boogaart


In addition to the things already mentioned, what you've forgotten in your specific Paste example are the CommandTarget and CommandParameter properties. For Paste, you can specify a TextBox by setting as the CommandTarget.

These properties are absolutely essential when want to use the same RoutedCommand from different controls. They allow you to give the Executed handler some information about the context in which the command is being invoked.

like image 38
Bubblewrap Avatar answered Sep 25 '22 02:09

Bubblewrap