# Friday, November 26, 2010

Command Changes in Prism 4

One small change that was made in Prism 4 was to update the DelegateCommand class to deal with command parameters a little more cleanly, and also to update the weak reference handling inside the DelegateCommand to work correctly based on the way Silverlight 4 implemented command hookup as opposed to WPF. Here is the scoop.

Command Parameters with DelegateCommand Need to Be Nullable

The ICommand.Execute and ICommand.CanExecute methods take a single parameter of type object. That parameter can be populated with a parameter by setting the CommandParameter property of a command source (such as a Button) to some object. However, because it is defined in terms of object and may never be set, the pattern establishes that the argument should be nullable.

DelegateCommand<T> in past releases of Prism allowed you to put a strongly typed wrapper around the parameter so that the target methods could just take in the argument type they expected to be provided when the method was invoked. So for example, if I have a SaveCommand property in my view model bound to a Button in the view, and I expected that the view would also pass the current customer by binding the CommandParameter property on the Button to an instance of a Customer (perhaps by binding it to the SelectedItem property in a data bound grid of customers), then I could just have a handling method like so:

   1: private void OnSaveCustomer(Customer cust)
   2: {
   3:     // Do what's needed to save
   4: }

That worked fine as long as the type you were passing was a reference type that could handle the fact that:

a) The view might not actually set the CommandParameter at all

b) Even if the CommandParameter is set to a Binding, at parse time the Binding might not resolve to a value yet and could pass a null when CanExecute is initially called.

But the strong typing on the DelegateCommand also made it look like it should be fine to do something like hook up to a DelegateCommand<int>. If you did though, you would likely run into a problem that down in the Prism code, there was an explicit cast to the target type. And if a null came through in the parse process or the CommandParameter was not set, you can’t cast null to int, so kaboom, deep down in the Prism code.

This is now fixed in Prism 4, although maybe not in the way you would expect. The Prism team initially looked into finding a way to just make it work with value types. But there was not really a way to do that without violating the principal of least surprise in some cases. The command method signatures imply nullability by being defined in terms of type object. Putting a strongly typed wrapper on there to avoid having to cast the parameters yourself is a nice convenience, but shouldn’t change the semantics of the underlying interface.

So the fix in Prism 4 is that the constructor of DelegateCommand<T> checks to make sure the type argument T is either a reference type or a Nullable<T>. The reason it checks in the constructor instead of using a generic type constraint (such as the class constraint) is that Nullable<T> is actually a struct itself.

So the bad news is that if you had code that worked OK before passing value types for T with DelegateCommand<T>, you are going to have to change that code to use Nullable<T> instead to work in Prism 4. But really that is being done because even though it may have worked in some cases before, it was really violating the semantics of the command interface that the DelegateCommand represented and would not work consistently across the board with value types as a result.

DelegateCommand (Not of T)

Another common request in Prism was to have a non-generic DelegateCommand class. If you never intend to pass an argument, it was a pain to always have to declare your commands in terms of DelegateCommand<object> and then have a signature in your Execute and CanExecute handlers that took an object parameter that you always ignored. Now if you never expect a parameter to be passed to your command handlers, you can just define your command in terms of DelegateCommand, and the Execute and CanExecute handlers can just have no parameters (Action and Func<bool> respectively) so your code looks a little cleaner.

Because of this, you will also see that the common functionality is factored out to a DelegateCommandBase class that both DelegateCommand and DelegateCommand<T> derive from.

WeakReference Handling

One of the things the DelegateCommand does for you in Prism is that it tries to help protect you from leaking memory if the lifetimes of the command source (i.e. Button in a view) and the command handler (i.e. target method in a view model) are different. For example, in some scenarios, you might choose to keep an instance of a view model around in memory, and create new instances of a view and bind each instance of the view to the view model only when it is being shown.

Until Silverlight 4, there were no built in command handlers, so this was really only relevant to WPF anyway. And WPF does things a little differently under the covers than the implementation that ended up in Silverlight 4. In WPF, in addition to holding a reference to the command object itself ( so that Execute and CanExecute can be called), the command source (i.e. Button) holds a reference to the delegate instance that exposed the CanExecuteChanged event (which would be something like your view model, as opposed to the command object itself). Silverlight 4 does not hold that additional reference.

So that required a small change that you might run across if you are looking at the code, where the DelegateCommand uses a weak reference wrapper to command source when you are in WPF and not in Silverlight. This is to accommodate this difference in the platforms.

Bottom line, the weak reference is used in WPF to avoid leaking memory if the command source comes and goes and the command target sticks around, but not used in Silverlight because it is not needed.

Summary

That is about it as far as changes to commands. Bottom line, any code you had before should work as it was unless you were using value types as parameters. In that case you will need to change them to take Nullable<yourvaluetype> to work with Prism 4. The weak reference stuff will continue to work as it always has, but be correct for the Silverlight reference handling which is different under the covers than the WPF hookup. And having a parameterless option for commands is a handy addition I know I will use a lot.





Friday, November 26, 2010 9:59:06 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 


 # Thursday, November 25, 2010

WCF RIA Services Part 9–Structuring Your Application is Online

Part 9 of my WCF RIA Services article series is now available here. This episode talks about how to break your application solution up into multiple libraries and layers on the server side and how to break the client side up into multiple modules. I talk about how to use MEF to asynchronously download client modules and how to overcome a limitation in the Visual Studio tooling when you do that for setting your RIA Services link between the client and server projects.

Enjoy!





Thursday, November 25, 2010 1:25:03 PM (GMT Standard Time, UTC+00:00)
Comments [0]  | 


 # Monday, November 15, 2010

Prompting the User From a View Model–Prism 4 Gems

Prism 4 is out at last and has a lot of goodness added to what was already there from previous versions. I’ve obviously got a biased view – I had the privilege to work directly as a part time member of the team on Prism 4 as I did on Prism 1. That just means I was there enough to annoy the team and maybe help steer them in the right direction at times, although for the most part they didn’t need much steering as they are an incredibly talented and fun group to work with.

In Prism 4, you’ve still got the modularity, UI composition (regions), commands and events from Prism 2.2 and prior that work with both WPF and Silverlight. In addition, you’ve now got some great guidance on how to do the MVVM pattern, navigation, and using MEF for your dependency injection container under the covers instead of Unity. I’ll be posting some other articles on those features in the near future.

Along with the major features of Prism, there is an awful lot of useful code in the QuickStarts and RI samples that come along with Prism, and a few useful behaviors and coding patterns that were written in the process of fleshing out the MVVM pattern guidance – the hidden gems of Prism. This post will highlight one of those – interaction requests. This post assumes you are familiar with the MVVM pattern and the reasons why you would want to separate your view and your view model, as well as the standard structure of the MVVM pattern (View.DataContext  = ViewModel). The key things to keep in mind for what I am going to cover here is the it is the view’s responsibility to determine the visual rendering of a part of the application functionality, it is the view model’s job to encapsulate the state and logic that support that view without being coupled to the view too tightly and without specifying visual aspects directly itself. When doing MVVM right, you should be able to hand the view’s XAML over to a designer, allow them to change every single element in there if they choose to, and not break the application as long as they maintain the bindings that were in the view so they display things in similar ways.

How Hard Can a MessageBox Be?

Strangely enough, when you start doing the MVVM pattern, one challenge you quickly come across is that one of the most conceptually simple tasks in UI development suddenly becomes hard. A very common question is “How can I pop a MessageBox or prompt the user from my view model?” If done right, the view model is the place the logic will reside that determines when it is time to prompt the user. It may be based on some validation error, but for that you should probably be using the native validation mechanisms of WPF or Silverlight. But more likely it is because an async service call failed or something else happened in the background, and you need to notify the user and possibly collect an answer from them.

The obvious and simple answer is that a view model could simply do a MessageBox.Show(), ChildWindow.Show() in Silverlight, or Window.Show() in WPF. However, that would both be a violation of the design pattern because now you are not leaving all aspects of the visual presentation up to the view, and it would also limit the testability of your view model because that popping of dialogs is not going to work so well from an automated unit test.

So how can you show a prompt to the user without showing a prompt to the user? Well, there are a couple of ways you could go about it. But the way the Prism team came up with is simple, elegant, and Blendable, so what more do you need?

Step 1: Expose a Property of type IInteractionRequest from your ViewModel

The IInteractionRequest interface in the Prism.Interactivity library defines a simple API for a view model to notify a view when it needs an interaction with the user. It simply exposes an event that can be raised to the view:

   1: public interface IInteractionRequest
   2: {
   3:     event EventHandler<InteractionRequestedEventArgs> Raised;
   4: }

 

The event args carry along some information that can be used to prompt the user (just as data, not appearance) and the ability to wait and call back when that interaction is done:

   1: public class InteractionRequestedEventArgs : EventArgs
   2: {
   3:     public Action Callback { get; }
   4:     public Notification Context { get; }
   5: }

 

The Notification object just has a Content property of type object (which the view can put a data template on for rendering of complex information) and a string Title property, assuming you might want to present a pop up with a title of some sort in the view, but not requiring it.

There is a concrete implementation of this interface in Prism 4 called InteractionRequest<T> that has a pre-built behavior for the client side that can show a notification window (OK/Cancel) with minimal hook up. It is also extensible in that you can provide a custom template for the rendering of the window so you could accommodate Yes/No/Cancel or other kinds of user prompting with minimal effort.

So the first thing is to expose an IInteractionRequest property from the view model, using the InteractionRequest<Confirmation> type to make it minimal code for your view model.

   1: public SomeViewModel()
   2: {
   3:     DoWorkCommand = new DelegateCommand(OnDoWork);
   4:     PromptUserRequest = new InteractionRequest<Confirmation>();
   5: }
   6: public InteractionRequest<Confirmation> PromptUserRequest { get; private set; }
   7: public ICommand DoWorkCommand { get; private set; }
   8:  
   9: private void OnDoWork()
  10: {
  11: }

 

Step 2: Raise the Raised event from the ViewModel When Appropriate

When you want to prompt the user from the view model, simply call the Raise method on the InteractionRequest<T>, supplying the appropriate confirmation arguments.

   1: private void OnDoWork()
   2: {
   3:     // Do some work, then prompt the user
   4:     PromptUserRequest.Raise(
   5:         new Confirmation { Content = "Work has been done", 
   6:                            Title = "View model notification" }, 
   7:         (cb) => { UserInputResult = cb.Confirmed ? 
   8:                   "User clicked OK" : "User cancelled"; });
   9: }

Again, the content could be a whole object tree that can be rendered via a custom data template in the view, but in this case I am just showing simple text.

If you have further work to do after the user input is complete, you can handle the callback as I am showing here and you will be passed a Confirmed flag to tell whether they picked OK or Cancel. If you don’t need confirmation, you can just use InteractionRequest<Notification> as well.

Step 3: Add the InteractionRequestTrigger and PopupChildWindowAction Behavior to Your View

These two objects constitute a behavior based on the Blend SDK that get attached to your view through the Interaction.Triggers attached property. If you have not heard of Blend Behaviors before, do some quick reading here. The InteractionRequestTrigger binds to the exposed IInteractionRequest property on your view model, firing when the Raised event happens. The PopupChildWindowAction works in Silverlight to create a ChildWindow with OK/Cancel buttons and by default sets the Content property of the Notification object you pass when firing the event as the Content of the ChildWindow. It also sets the Title as the Title not surprisingly.

   1: <UserControl ...>
   2:     <UserControl.DataContext>
   3:         <local:SomeViewModel />
   4:     </UserControl.DataContext>
   5:     <i:Interaction.Triggers>
   6:         <prism:InteractionRequestTrigger SourceObject="{Binding PromptUserRequest}">
   7:             <prism:PopupChildWindowAction/>
   8:         </prism:InteractionRequestTrigger>
   9:     </i:Interaction.Triggers>

 

In this simple sample, when the user presses the button hooked up to the DoWorkCommand, they will see:

11-14-2010 8-35-23 PM

Pretty simple. If you wanted to put a custom rendering on the Content object, you would just define a data template as a resource and point to it from the ContentTemplate property on the PopupChildWindowAction:

   1: <UserControl.Resources>
   2:     <DataTemplate x:Key="flipIt">
   3:         <TextBlock Text="{Binding}" FontSize="25" FontFamily="Comic Sans MS"/>
   4:     </DataTemplate>
   5: </UserControl.Resources>
   6: <i:Interaction.Triggers>
   7:     <prism:InteractionRequestTrigger SourceObject="{Binding PromptUserRequest}">
   8:         <prism:PopupChildWindowAction ContentTemplate="{StaticResource flipIt}"/>
   9:     </prism:InteractionRequestTrigger>
  10: </i:Interaction.Triggers>

 

That’s all there is to it.

All of this applies to the WPF side of the house as well other than the PopupChildWindowAction. That is only in Prism for Silverlight, although it would be a simple matter to migrate the code to WPF. I’ll save that for a future post.

Enjoy. You can download the sample code here.





Monday, November 15, 2010 2:11:08 AM (GMT Standard Time, UTC+00:00)
Comments [14]  | 


 # Friday, November 5, 2010

Slides and Demos from DevConnections

I gave four talks at DevConnections this week – two on RIA Services, one on Prism, and one on WPF Client Security.

To those who attended, thanks for the great participation and questions!

To anyone who wants the slides and code, you can find those below.

Build N-Tier Apps with WCf RIA Services   Slides   Demos

Deep Dive into WCF RIA Services   Slides   Demos

Build Composite WPF and Silverlight Apps with Prism 4    Slides    Demos

WCF Client Security   Slides   Demos

Enjoy!





Friday, November 5, 2010 12:04:05 AM (GMT Standard Time, UTC+00:00)
Comments [0]  | 


















June, 2013 (1)
May, 2013 (2)
April, 2013 (2)
March, 2013 (2)
February, 2013 (2)
January, 2013 (2)
December, 2012 (3)
November, 2012 (1)
October, 2012 (1)
August, 2012 (2)
June, 2012 (2)
May, 2012 (3)
April, 2012 (1)
March, 2012 (2)
February, 2012 (2)
January, 2012 (1)
November, 2011 (4)
October, 2011 (1)
September, 2011 (2)
August, 2011 (1)
July, 2011 (1)
May, 2011 (5)
March, 2011 (4)
February, 2011 (2)
January, 2011 (3)
November, 2010 (4)
October, 2010 (1)
September, 2010 (5)
August, 2010 (5)
July, 2010 (6)
June, 2010 (8)
May, 2010 (2)
April, 2010 (2)
January, 2010 (1)
December, 2009 (3)
November, 2009 (2)
October, 2009 (3)
September, 2009 (3)
August, 2009 (2)
July, 2009 (3)
May, 2009 (3)
April, 2009 (2)
March, 2009 (1)
February, 2009 (2)
January, 2009 (2)
December, 2008 (1)
November, 2008 (2)
October, 2008 (5)
September, 2008 (4)
August, 2008 (2)
July, 2008 (1)
June, 2008 (2)
May, 2008 (2)
April, 2008 (3)
February, 2008 (6)
January, 2008 (3)
December, 2007 (1)
November, 2007 (1)
October, 2007 (5)
September, 2007 (1)
July, 2007 (3)
June, 2007 (8)
April, 2007 (2)
March, 2007 (4)
February, 2007 (1)
December, 2006 (2)
November, 2006 (9)
October, 2006 (5)
September, 2006 (3)
August, 2006 (2)
July, 2006 (4)
June, 2006 (5)
May, 2006 (10)
April, 2006 (4)
March, 2006 (2)
February, 2006 (12)
January, 2006 (7)
December, 2005 (2)
November, 2005 (15)
October, 2005 (6)
September, 2005 (7)
August, 2005 (3)
July, 2005 (10)
June, 2005 (11)
May, 2005 (7)
April, 2005 (8)
March, 2005 (6)
February, 2005 (2)
January, 2005 (6)
December, 2004 (3)
November, 2004 (5)
October, 2004 (2)
September, 2004 (5)
August, 2004 (13)
July, 2004 (6)
June, 2004 (14)
May, 2004 (17)
April, 2004 (12)
March, 2004 (8)
February, 2004 (10)
January, 2004 (14)
December, 2003 (9)
November, 2003 (13)
October, 2003 (3)

Sign In
Copyright © 2006-2012 Brian Noyes. All rights reserved.

designed by NUKEATION STUDIOS