Advanced Command Binding Question (Not On Click)

Topics: Prism v2 - Silverlight 2
Jun 5, 2009 at 11:47 AM

Hi

I have a user control that up until now has had a MouseLeftButtonDown event on its outer border to handle any clicking on the control.

The click event causes a visual state manager change.

Now I am trying to refactor so MVVM is used and have a couple of questions:

1. The cal:Click.Command attribute does not work on the border (presumable because it does not handle the click event). Can anyone point me in the write direction of how to create a command for the MouseLeftButtonDown event or am I better off just making my whole user control a button with all the internal xaml declared in a style? Alternatively is there another container element or similar that i could wrap the control in that has a click event?

2. In the code behind previously I have VisualStateManager.GoToState(this,.... . How should this now be handled since my viewmodel does not have any reference to the view? One thought I had was to try the supervising controller pattern as described here: http://jonas.follesoe.no/CombiningDifferentSeparatedPresentationPatterns.aspx. Is there a cleaner way than this?

Thanks

Mark

Jun 5, 2009 at 9:39 PM

Hi Mark,

 

I will try to answer your questions separately.

 

Command Attached Behavior

Some time ago, I created a blog post that explains how to create a command with an attached behavior for a Silverlight 3 DataForm’s particular event. This scenario appears to be very similar, so the following links might be of use:

·         Commands with Attached Behavior for Silverlight 3 DataForm

·         Commands (Extending Command Support part)

 

 

ViewModel and View reference

I do not know your exact scenario, but if your ViewModel does not have a reference to the view the usual approach would be to have a reference to the ViewModel (then you would be able to call the methods of the model from the view). If for a particular reason this is not the scenario you have implemented, you could always use the Prism EventAggregator to publish an event in the view and subscribe to it in the model. However, this might be a bit of an overkill in this situation (again, this would depend on your application needs).

Ward Bell also blogged about his approach here, you might find it interesting.

 

The following section from the Composite WPF & SL KB has some articles about MVVM:

·         Model View ViewModel (MVVM)

Please let me know if this helps.

 

Damian Schenkelman

http://blogs.southworks.net/dschenkelman

Jun 5, 2009 at 10:02 PM

Re Q1

I will give this I try thanks.

Re Q2

I saw in one of the articles in the knowledge base (http://www.global-webnet.net/BlogEngine/post/2008/09/08/Composite-WPF-Obtaining-View-reference-with-Presentation-Model.aspx) that Bill Kratochvil actually passes in the view to the Command as a Command Parameter

Another option I have seen floating around is the use of the Blend3 attached behaviours. If I did this is it straight forward to access the VM from the behaviour code?

I guess I had hoped there would be a straight forward MVVM pattern to handle a the scenario where an event needs to cause a change to both the data (VM) and the XAML. Sounds like something good to blog about when I figure it out!

Thanks again

Jun 8, 2009 at 10:26 AM

I'm afraid I gave up and was able to do what I wanted by treating my control as a checkbox and completing changing the control template. All the visual changes I needed where just handled in the visual state manager.

Damian my view does not have a direct reference to my viewmodel because it is injected as the datacontext with Ninject. Is it possible to call the commands I have created or somehow get and set the properties of my datacontext?

 

Jun 8, 2009 at 6:49 PM

Hi Mark,

 

I have not used NInject, but as you said after performing DI the ViewModel is injected as the the dataContext in the view.

 

In this case, although you do not have a property that is of the ViewModels type inside your view (private IViewModel model), you do have a reference to the ViewModel (through the datacontext). Therefore, all you have to do to access the view model's public properties is cast your data context to your view model's type:

IViewModel model = (IViewModel)this.DataContext;

ICommand command = model.Command1;

 

Of course this depends on your implementation, but the main idea should be the same.

 

I hope you can find this useful.

 

Damian Schenkelman

http://blogs.southworks.net/dschenkelman