Binding Commands in M-V-VM

461 views
Skip to first unread message

Corrado Cavalli

unread,
Jul 21, 2008, 2:50:47 PM7/21/08
to wpf-di...@googlegroups.com

I’m reviewing some courseware and I’d like to update the M-V-VM part.

 What I’m looking for is a way to easily bind routedcommands exposed by viewmodel inside the view.

This is the cleanest solution I’ve found:

http://blogs.msdn.com/dancre/archive/2006/09/15/dm-v-vm-part-7-encapsulating-commands.aspx but it doesn’t work with multiple commands.

 

What I’d like to have is something like

 

<Grid>

<l:CommandBinder>

<CommandBinder BindTo:{AddCommand} />

<CommandBinder BindTo:{RemoveCommand} />

</l:CommandBinder>

</Grid>

 

Where Add/RemoveCommand are routed command exposed from associated DataContext.

Anyone has an idea of how to bind a command w/o using CommandBinding object?

 

Corrado

Mike Brown

unread,
Jul 21, 2008, 5:06:25 PM7/21/08
to wpf-di...@googlegroups.com
Oh Max oh max, we barely knew thee.
 
I'll probably be looking at this again. Someone mentioned that their ICommands on the Presentation Model weren't getting any CanExecute queries from the UI. I've got to do a few things back in the WPF arena soon anyway, so it'll definitely be a stop on my tour.
 
--Mike

Corrado Cavalli

unread,
Jul 22, 2008, 3:05:30 PM7/22/08
to wpf-di...@googlegroups.com

Tested it and everything works fine, apart the previously mentioned problem…

 

Corrado

<br

Josh Smith

unread,
Jul 23, 2008, 11:15:02 PM7/23/08
to wpf-di...@googlegroups.com
Corrado,

What does not work for you in this solution?  Expose ICommand objects off your ViewModel, and then bind control properties to those props.  Give the ICommand objects a reference to the ViewModel that exposes it as a property, so that you can read/modify the ViewModel from the Command itself.

You can see this exact approach in use in the Text Search demo here:

http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx

Does that not work for you?

Josh

Corrado Cavalli

unread,
Jul 24, 2008, 12:27:47 AM7/24/08
to wpf-di...@googlegroups.com

Hi Josh,

I’d like the idea of using RoutedCommands instead of ICommand so that I could handle commands coming from different sources instead of wiring each command straight to the command and I’m looking for a clean solution (if any) that allows me to do that w/o using CommandBinding but just specifying the command name as Dan’s sample does.

 

What’s your approach if you need to handle the same command coming from different sources?

 

Corrado

Josh Smith

unread,
Jul 24, 2008, 9:05:25 AM7/24/08
to wpf-di...@googlegroups.com
Corrado,

I must be misunderstanding something.  According to my line of thought, you could bind to the same command (exposed by ViewModel) from multiple controls.  Can you relate your question to a specific example please?

Josh

Bill Kempf

unread,
Jul 24, 2008, 10:06:28 AM7/24/08
to wpf-di...@googlegroups.com
I've struggled with this same thing.  Ideally, I want a commanding solution that allows the following:
 
1.  Support for the Name and Text properties.
2.  Support for InputGestures.
3.  Support for routing (despite the documentation given in Prism, there are valid reasons for wanting the bubbling/tunneling of events).
4.  Support for binding to handlers on external objects, not just on the current object in the codebehind.
5.  Relatively clean XAML code.
 
RoutedUICommand gives us 1-3, but not 4 & 5.
 
DelegatingCommand gives us 4 & 5.
 
CommandModel gives us 1-3 and limited support for 4 & 5 (it's not very flexible with 4, since the binding's not declarative, and 5 is debatable when discussing the aesthetics, and falls down when trying to specify multiple bindings).
 
I've been working on something that allows you to do the following (lots of XAML left out for clarity purposes).
 
<Window mvp:Presenter.Instance="{x:Type SomePresenter}">
   <mvp:Presenter.ActionBindings>
       <mvp:ActionBindings>
           <mvp:CommandActionBinding Command="ApplicationCommands.Close"
               Executed="OnClose"
               CanExecute="CanClose"/>
       </mvp:ActionBindings>
   </mvp:Presenter.ActionBindings>
</Window>
 
Presenter.Instance is an attached property that associates a presenter with a portion of the UI (inherited, so generally just set on the root).  If a Type is used here, a new instance is instantiated.
 
Presenter.ActionBindings is an attached collection property.  Unfortunately, because there's currently no way to lazily create the collection (if anyone can figure out a clever hack around that, please do share) we have an extra element (mvp:ActionBindings) that makes the XAML less clean then I'd like.  ActionBindings come in two flavors: CommandActionBinding and EventActionBinding.  CommandActionBindings specify handlers for Executed and CanExecute that are on the Presenter.Instance instead of on the codebehind.  This magic is achieved through reflection, so there are some considerations here, but it works nicely.  The EventActionBinding connects handlers on the Presenter.Instance to an event on the UI element, also via reflection.
 
This works well enough for an MVPoo pattern of constructing a UI.  It doesn't address some concerns when it comes to a modular/composite application, and I'm still working on good techniques for that.
 
I don't have much code to share at this point.  I'm still designing some of this.  For instance, I'd like the ActionBindings to do some of the magic found in Caliburn's ActionMessages (http://devlicio.us/blogs/rob_eisenberg/archive/2008/01/09/caliburn-using-actionmessages-to-enable-mvc-in-wpf.aspx).  If anyone is interested in collaborating on a design/implementation of this, I'd be very interested.
  


War is peace. Freedom is slavery. Bugs are features.

Josh Smith

unread,
Jul 24, 2008, 10:11:47 AM7/24/08
to wpf-di...@googlegroups.com
That is very interesting, Bill.  I'd like to work on that with you.

Josh

Bill Kempf

unread,
Jul 24, 2008, 10:16:23 AM7/24/08
to wpf-di...@googlegroups.com
OK, I'm hip deep in a few things at work currently, but we need to start working on these concepts, so I'll try to get into it this afternoon and supply you with some work in progress stuff later today or tomorrow.
 
I assume I should take this discussion off the list and e-mail you directly?

Josh Smith

unread,
Jul 24, 2008, 10:17:29 AM7/24/08
to wpf-di...@googlegroups.com
Yeah, direct contact is better. Thanks

Sacha Barber

unread,
Jul 24, 2008, 10:31:39 AM7/24/08
to wpf-di...@googlegroups.com
We shall all look forward to what you both up with.

Thanks guys


Date: Thu, 24 Jul 2008 10:16:23 -0400
From: wek...@gmail.com

Get fish-slapping on Messenger! Play Now

Mike Brown

unread,
Jul 24, 2008, 11:56:59 AM7/24/08
to wpf-di...@googlegroups.com
Bill,
 
I believe if you initialize decorate the ActionBindings class with a ContentPropertyAttribute  it should allow you to initialize without the extra line. Of course that requires you to actually create the ActionBindings class instead of using a generic list.
 
The fix for DanCre's commandmodel to make it support multiple bindings seemed pretty straightforward to me. Regarding Asthetics it can always be improved with a MarkupExtension or twenty ;)
 
Keep me posted on what you come up with.

Bill Kempf

unread,
Jul 24, 2008, 3:28:35 PM7/24/08
to wpf-di...@googlegroups.com
Mike,
 
I have zero issues with the ActionBindingCollection not being a generic list.  In fact, to make the magic work, it can't be.  However, I don't quite see how ContentPropertyAttribute applies to the problem here?  Can you illustrate with code?

Corrado Cavalli

unread,
Jul 24, 2008, 4:03:27 PM7/24/08
to wpf-di...@googlegroups.com

Bill summarized my idea, what I don’t really like in Bill’s snippet:

 

<Window mvp:Presenter.Instance="{x:Type SomePresenter}">

   <mvp:Presenter.ActionBindings>

       <mvp:ActionBindings>

           <mvp:CommandActionBinding Command="ApplicationCommands.Close"

               Executed="OnClose"

               CanExecute="CanClose"/>

       </mvp:ActionBindings>

   </mvp:Presenter.ActionBindings>

</Window>

 

Is the presence of delegate method names inside the Xaml

I really love to have something like (in pseudoXaml)

 

<Window>

<x:CommandBinder>

<CommandBind BindTo:{Commands.Open} />

<CommandBind BindTo:{Commands.Open} />

</x:CommandBinder>

<Window>

 

Hope your clever minds could make me say “Yess!” J

Josh Smith

unread,
Jul 24, 2008, 4:10:56 PM7/24/08
to wpf-di...@googlegroups.com
Corrado,

I still don't understand what it is you're trying to do that is not handled by binding to an ICommand property of the ViewModel.  Why does that not suit your needs?  What am I missing here???

Josh

Bill Kempf

unread,
Jul 24, 2008, 4:20:40 PM7/24/08
to wpf-di...@googlegroups.com
In your example code, I don't see how the two CommandBind elements differ.  I don't understand what's meant to be accomplished.

Corrado Cavalli

unread,
Jul 24, 2008, 4:25:08 PM7/24/08
to wpf-di...@googlegroups.com

Josh,

ICommand (the one you use in your great article J fit my needs) but I also love RoutedCommand so I’d  like to expose RoutedCommands from ViewModel and wire them up via Xaml in the cleanes mode as possible (see my previous pseudo-sample)

Basically, I like Bill’s solution apart comment I exposed in my previous post, don’t know If my idea it’s applicable but that’s what I’d love to see.

Josh Smith

unread,
Jul 24, 2008, 4:29:18 PM7/24/08
to wpf-di...@googlegroups.com
Corrado,

What is the advantage of using routed commands if you always want your ViewModel to handle the command execution?  What benefit does the routing of command execution notifications bring to the table if the intended recipient of those notifications is known beforehand?

Josh

Corrado Cavalli

unread,
Jul 24, 2008, 4:31:35 PM7/24/08
to wpf-di...@googlegroups.com

Oops sorry, I meant:

 

<Window>

<x:CommandBinder>

<CommandBind BindTo:{Commands.Open} />

<CommandBind BindTo:{Commands.Close} />

</x:CommandBinder>

<Grid>

<Button Command={Binding Commands.Open} />

<Button Command={Binding Commands.Close} />

</Grid>

<Window>

 

In short: I’d like to have the CommandBinding behavior but w/o specifying method names (wiring should happen inside viewmodel in the same way exposed by Dan’s code) but I have absolutely idea if this is possible.

Bill Kempf

unread,
Jul 24, 2008, 4:44:26 PM7/24/08
to wpf-di...@googlegroups.com
Josh,
 
From my point of view, and some of the user stories behind why I'm designing the ActionBindings:
 
*  Depending on the nature of how the command was initiated, we may want to bind to different handlers.  For instance, a DeleteCommand may be used on two different buttons, meant to remove items from two different lists.  The Presenter should be ignorant of the View, so shouldn't know details about which button is clicked or if any button is clicked to initiate the command.  We could use multiple commands here, but that seems like overkill in this simple case, and may not even be possible in others (wanting to handle standard commands, for instance).  Of course, this point doesn't seem to apply to Corrado's scenario, since he explicitly doesn't want to specify the handler.
 
*  We want to be able to bind commands we don't have control over the definition of.  We can't make the command a DelegatingCommand concept, because the command was already defined as a Routed(UI)Command.  I have no idea if this applies to Corrado.
 
*  We may actually be routing to different Presenters in a composite application.  This is very similar to the first point, but instead of different handlers, we have entirely different target objects.
 
* Routed(UI)Commands give us more functionality than just the routing.  The InputGestures, Name and Text are all handy features to lose.
I don't know what specific reason(s) Corrado has.  They may even be reason(s) I don't list.

Bill Kempf

unread,
Jul 24, 2008, 4:52:45 PM7/24/08
to wpf-di...@googlegroups.com
Yes, this is possible.  At one point I had something similar to this.  The CommandBinder performed some magic to call a Bind(CommandBindingCollection, ICommand) on the Presenter/ViewModel, which than programatically created the bindings.  In fact, taking that approach, there's not even much reason to get that fancy.  The attached Presenter.Instance property can be made to call a simple Bind(CommandBindingCollection) and Unbind(CommandBindingCollection) on the Presenter.  All the bindings would then be done in code, instead of declaratively.
 
<Window ui:Presenter.Instance="{x:Type MyPresenter}">
</Window>
 
public class MyPresenter
{
    private void Bind(CommandBindingCollection bindings)
    {
        // Code that adds CommandBinding instances for the commands we're interested in.
    }
 
    private void Unbind(CommandBindingCollection bindings)
    {
         // Code that removes the bindings
    }
}

This is a very simple concept and easy to implement.  It doesn't really make use of the routed nature of Routed(UI)Commands, but does make it trivial to bind them at the "root" level.

Corrado Cavalli

unread,
Jul 24, 2008, 4:59:27 PM7/24/08
to wpf-di...@googlegroups.com

I agree with your ideas, InputGesture and routing to different presenter are ideas I’ve considerated.

 

Corrado

Josh Smith

unread,
Jul 24, 2008, 5:07:50 PM7/24/08
to wpf-di...@googlegroups.com
See my comments inline...

On Thu, Jul 24, 2008 at 4:44 PM, Bill Kempf <wek...@gmail.com> wrote:
Josh,
 
From my point of view, and some of the user stories behind why I'm designing the ActionBindings:
 
*  Depending on the nature of how the command was initiated, we may want to bind to different handlers.  For instance, a DeleteCommand may be used on two different buttons, meant to remove items from two different lists.  The Presenter should be ignorant of the View, so shouldn't know details about which button is clicked or if any button is clicked to initiate the command.  We could use multiple commands here, but that seems like overkill in this simple case, and may not even be possible in others (wanting to handle standard commands, for instance).  Of course, this point doesn't seem to apply to Corrado's scenario, since he explicitly doesn't want to specify the handler.

[JAS] - According to my worldview, in the Delete scenario you described, I would have two instances of the Delete command (one class, two instances) exposed as properties of my ViewModel.  I would provide each instance with a delegate to invoke upon execution, in an IoC mode of thinking.
 
*  We want to be able to bind commands we don't have control over the definition of.  We can't make the command a DelegatingCommand concept, because the command was already defined as a Routed(UI)Command.  I have no idea if this applies to Corrado.

[JAS] - No comment.
 
*  We may actually be routing to different Presenters in a composite application.  This is very similar to the first point, but instead of different handlers, we have entirely different target objects.

[JAS] - Since, in my approach, every ViewModel object exposes its own private instance of a command class, that is not an issue.
 
* Routed(UI)Commands give us more functionality than just the routing.  The InputGestures, Name and Text are all handy features to lose.

[JAS] - That's a good point.  I can see the appeal of keeping gestures and localized display text around.  However, I should point out, input gestures are not exclusive to routed commands.  They work with any ICommand object.  And, of course, it's not too difficult to add a Text property to a custom command base class.

This is turning into a very interesting thread!!

josh

Bill Kempf

unread,
Jul 24, 2008, 7:12:07 PM7/24/08
to wpf-di...@googlegroups.com
Inline:

On Thu, Jul 24, 2008 at 5:07 PM, Josh Smith <flappl...@gmail.com> wrote:
See my comments inline...

On Thu, Jul 24, 2008 at 4:44 PM, Bill Kempf <wek...@gmail.com> wrote:
Josh,
 
From my point of view, and some of the user stories behind why I'm designing the ActionBindings:
 
*  Depending on the nature of how the command was initiated, we may want to bind to different handlers.  For instance, a DeleteCommand may be used on two different buttons, meant to remove items from two different lists.  The Presenter should be ignorant of the View, so shouldn't know details about which button is clicked or if any button is clicked to initiate the command.  We could use multiple commands here, but that seems like overkill in this simple case, and may not even be possible in others (wanting to handle standard commands, for instance).  Of course, this point doesn't seem to apply to Corrado's scenario, since he explicitly doesn't want to specify the handler.

[JAS] - According to my worldview, in the Delete scenario you described, I would have two instances of the Delete command (one class, two instances) exposed as properties of my ViewModel.  I would provide each instance with a delegate to invoke upon execution, in an IoC mode of thinking.
 
[WEK] - I mentioned the multiple command types, and tried to give reasons why it's at best a less than ideal solution.  Let me give a better example.  Instead of Delete, the commands we want to handle on the lists are Cut/Copy/Paste.  Even a custom command could have problems here, since we want a single InputGesture that behaves differently depending on the focus.

 
*  We want to be able to bind commands we don't have control over the definition of.  We can't make the command a DelegatingCommand concept, because the command was already defined as a Routed(UI)Command.  I have no idea if this applies to Corrado.

[JAS] - No comment.
 
[WEK] - This is actually one of the most compelling reasons to me.

 
*  We may actually be routing to different Presenters in a composite application.  This is very similar to the first point, but instead of different handlers, we have entirely different target objects.

[JAS] - Since, in my approach, every ViewModel object exposes its own private instance of a command class, that is not an issue.
 
* Routed(UI)Commands give us more functionality than just the routing.  The InputGestures, Name and Text are all handy features to lose.

[JAS] - That's a good point.  I can see the appeal of keeping gestures and localized display text around.  However, I should point out, input gestures are not exclusive to routed commands.  They work with any ICommand object.  And, of course, it's not too difficult to add a Text property to a custom command base class.
 
[WEK] - Yeah, it would certainy be possible to implement all of the needed functionality in any old ICommand... but if you're going to do that every time, it seems like at least as complicated as any solution to bind to other objects.

Josh Smith

unread,
Jul 24, 2008, 7:17:40 PM7/24/08
to wpf-di...@googlegroups.com
Good points.  When I said, No Comment, it was because I agreed!  :)

Josh

Josh Smith

unread,
Jul 25, 2008, 12:02:15 AM7/25/08
to wpf-di...@googlegroups.com
My brain caught on fire tonight and I worked for seven straight hours on an implementation for what Corrado described (or something like it).  I also published an article about it, here: http://www.codeproject.com/KB/WPF/VMCommanding.aspx

Josh

On Mon, Jul 21, 2008 at 2:50 PM, Corrado Cavalli <corrado...@gmail.com> wrote:

Corrado Cavalli

unread,
Jul 25, 2008, 12:18:40 AM7/25/08
to wpf-di...@googlegroups.com

Josh,

You’re my hero!

I’ll have a look at it asap J

 

Amazing

Corrado

 

From: wpf-di...@googlegroups.com [mailto:wpf-di...@googlegroups.com] On Behalf Of Josh Smith
Sent: venerdì 25 luglio 2008 06:02
To: wpf-di...@googlegroups.com
Subject: Re: Binding Commands in M-V-VM

 

My brain caught on fire tonight and I worked for seven straight hours on an implementation for what Corrado described (or something like it).  I also published an article about it, here: http://www.codeproject.com/KB/WPF/VMCommanding.aspx

Josh

Josh Smith

unread,
Jul 25, 2008, 12:20:33 AM7/25/08
to wpf-di...@googlegroups.com
I hope it's what you need, Corrado!  :)

Josh

Mike Brown

unread,
Jul 25, 2008, 1:38:42 AM7/25/08
to wpf-di...@googlegroups.com
Josh,
 
From my point of view, and some of the user stories behind why I'm designing the ActionBindings:
 
*  Depending on the nature of how the command was initiated, we may want to bind to different handlers.  For instance, a DeleteCommand may be used on two different buttons, meant to remove items from two different lists.  The Presenter should be ignorant of the View, so shouldn't know details about which button is clicked or if any button is clicked to initiate the command.  We could use multiple commands here, but that seems like overkill in this simple case, and may not even be possible in others (wanting to handle standard commands, for instance).  Of course, this point doesn't seem to apply to Corrado's scenario, since he explicitly doesn't want to specify the handler.
 
   If you want to have the command act on a different List based on which button you pressed, you send the list as the command parameter...are we forgetting that this exists? I don't think routed commands are necessary at all.

 
*  We want to be able to bind commands we don't have control over the definition of.  We can't make the command a DelegatingCommand concept, because the command was already defined as a Routed(UI)Command.  I have no idea if this applies to Corrado.
In this case we expose a Static ICommand object that was implemented somewhere else. How does a routed command help anymore in this situation.

*  We may actually be routing to different Presenters in a composite application.  This is very similar to the first point, but instead of different handlers, we have entirely different target objects.
 
In that case the Presenter you're binding to should expose the command

* Routed(UI)Commands give us more functionality than just the routing.  The InputGestures, Name and Text are all handy features to lose.
I don't know what specific reason(s) Corrado has.  They may even be reason(s) I don't list
 
Bill, we discussed how to do all of those on Brownie Points so you don't lose any of the RoutedUICommand benefits. I think RUICommands are a necessity to address the needs of a non MVC/P/Whatever app. I still stand unconvinced that they provide anything above and beyond what can be done (easier) with generic ICommands.

Mike Brown

unread,
Jul 25, 2008, 1:44:05 AM7/25/08
to wpf-di...@googlegroups.com
Josh,
 
Your solution is implemented in Prism as the EventBroker combined with DelegateCommand.

Mike Brown

unread,
Jul 25, 2008, 1:45:43 AM7/25/08
to wpf-di...@googlegroups.com
BTW, you seem a lot happier in the new pic!

Josh Smith

unread,
Jul 25, 2008, 6:55:49 AM7/25/08
to wpf-di...@googlegroups.com
Thanks Mike!  :)

Josh

Bill Kempf

unread,
Jul 25, 2008, 10:06:38 AM7/25/08
to wpf-di...@googlegroups.com
On Fri, Jul 25, 2008 at 1:38 AM, Mike Brown <mbro...@gmail.com> wrote:
Josh,
 
From my point of view, and some of the user stories behind why I'm designing the ActionBindings:
 
*  Depending on the nature of how the command was initiated, we may want to bind to different handlers.  For instance, a DeleteCommand may be used on two different buttons, meant to remove items from two different lists.  The Presenter should be ignorant of the View, so shouldn't know details about which button is clicked or if any button is clicked to initiate the command.  We could use multiple commands here, but that seems like overkill in this simple case, and may not even be possible in others (wanting to handle standard commands, for instance).  Of course, this point doesn't seem to apply to Corrado's scenario, since he explicitly doesn't want to specify the handler.
 
   If you want to have the command act on a different List based on which button you pressed, you send the list as the command parameter...are we forgetting that this exists? I don't think routed commands are necessary at all.
 
[WEK] - No, I did not forge the parameter.  However, that approach can be complicated.  There's only one parameter.  If I need that parameter for other information, then the only alternative with this approach is to use a compound parameter.  However, compound parameters are extremely tricky to use declaratively.  Not that I'm saying you can't, just that it becomes an overly complex alternative.
 
 
*  We want to be able to bind commands we don't have control over the definition of.  We can't make the command a DelegatingCommand concept, because the command was already defined as a Routed(UI)Command.  I have no idea if this applies to Corrado.
In this case we expose a Static ICommand object that was implemented somewhere else. How does a routed command help anymore in this situation.
 
[WEK] - That Static ICommand object happens to be a RoutedUICommand, and there's nothing you can do about it, because you don't have control over the command's definition.
 

*  We may actually be routing to different Presenters in a composite application.  This is very similar to the first point, but instead of different handlers, we have entirely different target objects.
 
In that case the Presenter you're binding to should expose the command
 
[WEK] - This relies on using a different command, which I pointed out isn't always desirable, much less possible.
 

* Routed(UI)Commands give us more functionality than just the routing.  The InputGestures, Name and Text are all handy features to lose.
I don't know what specific reason(s) Corrado has.  They may even be reason(s) I don't list
 
Bill, we discussed how to do all of those on Brownie Points so you don't lose any of the RoutedUICommand benefits. I think RUICommands are a necessity to address the needs of a non MVC/P/Whatever app. I still stand unconvinced that they provide anything above and beyond what can be done (easier) with generic ICommands.
 
[WEK] - I think you and I disagree on the "easier" part of this argument.  I think I've laid out fairly clear areas in which the DelegatingCommand concept is NOT easier to use.
 
I believe that if Microsoft had provided some way to specify a target object when declaring event handlers in XAML, none of this would even be discussed.  We'd all be doing something like this, and the DelegatingCommand never would have been born:
 
<Window>
   <Window.CommandBindings>
      <CommandBinding Command="foo:MyCommands.FooCommand" Executed="{Event Target={StaticResource MyPresenter}, Handler=OnFooCommand}"/>
   </Window.CommandBindings>
</Window>
 
I'm just trying to get as close to what I think we should have had to begin with, with what can be currently implemented.

Mike Brown

unread,
Jul 25, 2008, 1:39:10 PM7/25/08