An introduction to MEFedMVVM – PART 1

Some content may be out of date. See latest blog on changes made here.

Intro

This is a small introduction to MEFedMVVM, a library that I built with the help of some fellow WPF Disciples, Peter O’Hanlon and Glenn Block (aka Mr.MEF). This library will enable you to quickly create ViewModels that consume services and inject these ViewModels in your View’s DataContext. It will also enable you to work better with your fellow friend, “The Designer” by leveraging Design time data and many other UI friendly stuff. With this library you can create WPF/Silverlight applications seamlessly since the API is common for both WPF and Silverlight.

This framework works for SL 4, WPF (.NET4.0 ). And we only support Blend 4 RC or newer. MEFedMVVM does not work in Blend 4 Beta .

MEFedMVVM-Logo2

Goals

– Write code that works for SL and WPF.

– Enable Design time data.

– Enable loosely coupled bridge between View and ViewModel.

– Enable easy ViewModel discovery and injection mechanism.

– Make composition super easy by leveraging MEF capabilities (without coupling your code with MEF).

How do I use this thing?

Ok so these are the first 3 basic steps.

1. Add a reference to MEFedMVVM.WPF/MEFedMVVM.SL (you also have to add a reference to dlls that are located in the Dependencies folder of the Source code if you are not including the library source code in your solution.)

image

2. Add an attribute somewhere in your project to mark the assembly as a “MEFedMVVM” Assembly, [assembly: DesignTimeCatalogAttribute]. This is used so that MEFedMVVM only looks for exported items in the marked assemblies. This makes initialization faster.

Now begins the MEFedMVVM fun….

3. Make your ViewModel discoverable by decorating it with [ExportViewModel(“MyMEFedViewModel”)] and instruct the view to go find that ViewModel by setting an attached property meffed:ViewModelLocator.ViewModel="MyMEFedViewModel"

So the View looks like this

   1: <UserControl x:Class="MEFedMVVMDemo.Views.UsersScreen"


   2:              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"


   3:              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"


   4:              xmlns:meffed="http:\\www.codeplex.com\MEFedMVVM"


   5:              meffed:ViewModelLocator.ViewModel="MyMEFedViewModel">

and the ViewModel like this

   1: [ExportViewModel("MyMEFedViewModel")]


   2: public class TestViewModel { }

and viola that is it…. You run the project and magically the ViewModel gets injected in the View…

I must say, I cannot take the credit for this magic, it’s all powered by the mighty MEF!

Ok so we injected the ViewModel in the View, but where the hell is the Design time data???

well should I tell you or should I go to sleep ? mmmm…. thinking… still thinking… aa well might as well tell you now that I started right 😛

When creating ViewModels usually the data is coming from some service which is injected to the VM via Dependency injection. What MEFedMVVM will do for you is let you expose services and include meta data that gives extra information to the service. MEFedMVVM uses this Meta data to decide which service to give to the VM at runtime and which service to inject at Design time.

This is how you expose services (for runtime)

   1: [ExportService(ServiceType.Runtime, typeof(IUsersService))]


   2: public class UsersService : IUsersService

This is how you expose services (for design time)

   1: [ExportService(ServiceType.DesignTime, typeof(IUsersService))]


   2: public class DesignTimeUsersService : IUsersService

P.S you can also specify ServiceType.Both if you want the same service to be injected at runtime and design time.

Once you make your Services discoverable it’s time to start using them in your ViewModel. In order to do this, you must have your VM implement the IServiceConsumer interface, or if you are lazy like me just inherit from BaseViewModel. You also need to specify which services you want injected by specifying the different types in the ExportViewModel attribute. Something like this

   1: [ExportViewModel("VM1", typeof(IUsersService), typeof(IVisualStateManager), typeof(IDispatcherService))]


   2: public class TestViewModel : BaseViewModel

In the above code I am importing the IUserService, the IVisualStateManager and the IDispatcher service into my view model. These services are injected when MEFedMVVM creates an instance of the ViewModel into a ServiceLocator so you can get them by calling GetService<T>() from the OnServicesInjected method. the code for this looks something like this

   1: protected override void OnServicesInjectedOverride()


   2: {


   3:     var usersService = GetService<IUsersService>();


   4:     var dispatcherService = GetService<IDispatcherService>();


   5: }

You might ask yourself why can’t I just import the services by using a standard [Import] like in normal MEF. Basically when the MEFedMVVM is looking for the correct services it is also doing some extra stuff that I will talk about in following blog posts (but I know you are curious so I’ll give you a hint…. IVisualStateManager for example gets injected with the UIElement that is requesting the ViewModel so that then the ViewModel can execute state without coupling to the VSM)

What comes out of the box?

Out of the box this library supplies a number of things… here is a list of most of the stuff

Common Services

– IMediator (use this to communicate from one ViewModel to another.

– IViewStateManager (User this to invoke VisualStates from the ViewModel)

– IContainerStatus (Provides a loaded event and unloaded event, these are hooked to the loaded and unloaded events of the UIElement that is consuming the ViewModel)

– IDispatcher (Provides a way so that you can call BeginInvoke on the Dispatcher in a loosely coupled way so that you can mock this when doing unit tests)

– and many many many more to come….

– and many more you can create yourself.

Basically this library is still learning how to walk, its still a cute little baby… but the basics are in (so yea its a healthy cute baby)… I will talk more on how you can create your own services that BRIDGE the ViewModel and the View in my next post (yet yea I know, I know, you are curious… Implement IContextAware in your service and you get injected with the View that requested the ViewModel and then you can do what the hell you want :). but don’t tell anyone I told you 😛 )

Other stuff

DelegateCommand<T> (Used to create commands without having to create a separate class that implements ICommand)

BaseViewModel (Implement INotifyPropertyChanged and you can raise PropertyChanged notifications in a strongly typed manner i.e OnPropertyChanged(() => Users); . BaseViewModel also has some other benifits that I will discuss in my next post)

More stuff coming up … don’t don’t worry … we just built the basics here 🙂

Conclusion

Why do I think this library has a lot of potential? Well right now there are some things missing but the basics are there and it is really easy to add new stuff now that we have a solid base. There are loads of things that I did not mention in this post since I wanted this post to be just a mini introduction. I will have Part 2,3 n of this post coming up shortly where I will go into more dept of the library and how you can extend it and bend it to your will.

I suggest you download the code from CodePlex and start playing with it. Right now I really need your help and get as much feedback / bug reports as possible … WARNING: Right now I am doing loads of changes to the code so please do not use this in production projects.

I hope you like this new library… just a word of caution when using this library…. it can get really addictive 😛 myself am suffering this side effect right now … hehe 🙂

Part 2 here

Part 3 here

Part 4 here

Download source and MEF it up! http://mefedmvvm.codeplex.com/

Problem: Configuration system failed to initialize

I got this error today and I was shocked… The InnerException was saying something like this

Only one <configSections> element allowed per config file and if present must be the first child of the root <configuration> element.

 

Well I had ONLY 1 configSections element in my App.config…. After loads of hair pulling I discovered its because the <configSections> element has to be defined as the first element in the App.config. Well thanks for the very useful exception message!

I hope this helps whoever encounters the same error…

Working with the WPF VSM in an MVVM friendly manner

Lately I have been working a lot with Silverlight. While working on my first Silverlight project I encountered my first problem… There are no Triggers in SL!!! At first I was frustrated and started hitting my self in the head but hey SL is not that bad… SL has the Visual State Manager aka VSM which is a pretty awesome tool I must say. I still think SL should have Triggers for some tasks such as ControlTemplates and other tasks yet with VSM you can still get some cool stuff done 🙂

What really strikes me with the VSM is the way it is supported in Blend, and YES designers love VSM! With the VSM they can define states in an easy way (and yes these states transition and the designer has full control on the transitions done). They can navigate easily through states in Blend and even see the transitions being done in Blend there and then.

image

Going back to WPF one thing that is missing in WPF is a way how a designer can define animations that get Triggered when something happens… Or let me re phrase that…. There is no easy way, or better not as easy as the VSM 🙂

Triggers in WPF can invoke Storyboards yet still it feels like the WPF animation system does not have a nice way to dispatch animations… Enter the VSM for WPF.

Yes, VSM is available for WPF as well, and yes it is supported in Blend (you just have to do a little trick that you can find over here)

I created a sample project that leverages the VSM for its animations and yes its all MVVM (in the sample app you’ll see that I am also using design time data for blend and I also included a mini MVVM Libarary that I use to develop my everyday WPF projects 🙂 ).

 

Let’s Get Started

So let’s start by defining a state in Blend. In order to do so (assuming you followed the instructions to enable the VSM for WPF projects) you need to navigate to the States Tab and create a new state. Once the state is created and selected you’ll see that Blend will go to recording mode (just like it does when you are doing a normal WPF animation). Now you can change any property of any element and the Blend will record that and create the appropriate transitions for it.

image

Ok, now that we have the states defined in Blend what is next? well we need a way how to invoke these states for starters!

The Blend team were so kind to give us a Behavior called GoToStateAction. This behavior will basically invoke a state when an event is raised, for example if you have a button that should dispatch a new state, you simple find the GoToStateAction form the Asset tab and drag it on the button

image

Then you can set the properties for this behavior in the properties tab. There you can specify which state to select.

image

By doing these steps (define a state and use the GoToStateAction to invoke the state) you are already good to go. You can press F5 and you can see that when you click the button you get transitioned from one state to another. (P.S it’s important that you set a default transition time span otherwise you end up with no transition since the default is 0s).

 

This is all cool but what about MVVM ??

I hear you I hear you…. What if I have a ViewModel which needs to invoke a state change ?? Unfortunately this is not so straight forward… BUT of course there is a solution… I extended the GoToStateAction so that it can be hooked up from a ViewModel. Here is my extended version

   1: public class VisualStateManagerInvoker : GoToStateAction

   2: {

   3:     #region CurrentState

   4:  

   5:     /// <summary>

   6:     /// CurrentState Attached Dependency Property

   7:     /// </summary>

   8:     public static readonly DependencyProperty CurrentStateProperty =

   9:         DependencyProperty.RegisterAttached("CurrentState", typeof(string), typeof(VisualStateManagerInvoker),

  10:                                             new PropertyMetadata((string)null,

  11:                                                                  new PropertyChangedCallback(OnCurrentStateChanged)));

  12:  

  13:     /// <summary>

  14:     /// Gets the CurrentState property.  This dependency property 

  15:     /// indicates ....

  16:     /// </summary>

  17:     public static string GetCurrentState(DependencyObject d)

  18:     {

  19:         return (string)d.GetValue(CurrentStateProperty);

  20:     }

  21:  

  22:     /// <summary>

  23:     /// Sets the CurrentState property.  This dependency property 

  24:     /// indicates ....

  25:     /// </summary>

  26:     public static void SetCurrentState(DependencyObject d, string value)

  27:     {

  28:         d.SetValue(CurrentStateProperty, value);

  29:     }

  30:  

  31:     /// <summary>

  32:     /// Handles changes to the CurrentState property.

  33:     /// </summary>

  34:     private static void OnCurrentStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

  35:     {

  36:         if (GetGoToStateAction(d) == null)

  37:         {

  38:             var command = new RelayCommand(x => //where x is the state name passed as parameter

  39:             {

  40:                 var stateAction = new VisualStateManagerInvoker();

  41:                 stateAction.Attach(d);

  42:                 stateAction.UseTransitions = GetShouldUseTransition(d);

  43:                 stateAction.StateName = (string)x;

  44:                 stateAction.Invoke(null);

  45:             });

  46:             SetGoToStateAction(d, command);

  47:         }

  48:     }

  49:  

  50:     #endregion

  51:  

  52:     #region GoToStateAction

  53:  

  54:     /// <summary>

  55:     /// GoToStateAction Attached Dependency Property

  56:     /// </summary>

  57:     public static readonly DependencyProperty GoToStateActionProperty =

  58:         DependencyProperty.RegisterAttached("GoToStateAction", typeof(ICommand), typeof(VisualStateManagerInvoker),

  59:                                             new PropertyMetadata((ICommand)null));

  60:  

  61:     /// <summary>

  62:     /// Gets the GoToStateAction property.  This dependency property 

  63:     /// indicates ....

  64:     /// </summary>

  65:     public static ICommand GetGoToStateAction(DependencyObject d)

  66:     {

  67:         return (ICommand)d.GetValue(GoToStateActionProperty);

  68:     }

  69:  

  70:     /// <summary>

  71:     /// Sets the GoToStateAction property.  This dependency property 

  72:     /// indicates ....

  73:     /// </summary>

  74:     public static void SetGoToStateAction(DependencyObject d, ICommand value)

  75:     {

  76:         d.SetValue(GoToStateActionProperty, value);

  77:     }

  78:  

  79:     #endregion

  80:  

  81:     #region ShouldUseTransition

  82:  

  83:     /// <summary>

  84:     /// ShouldUseTransition Attached Dependency Property

  85:     /// </summary>

  86:     public static readonly DependencyProperty ShouldUseTransitionProperty =

  87:         DependencyProperty.RegisterAttached("ShouldUseTransition", typeof(bool), typeof(VisualStateManagerInvoker),

  88:                                             new PropertyMetadata((bool)true));

  89:  

  90:     /// <summary>

  91:     /// Gets the ShouldUseTransition property.  This dependency property 

  92:     /// indicates ....

  93:     /// </summary>

  94:     public static bool GetShouldUseTransition(DependencyObject d)

  95:     {

  96:         return (bool)d.GetValue(ShouldUseTransitionProperty);

  97:     }

  98:  

  99:     /// <summary>

 100:     /// Sets the ShouldUseTransition property.  This dependency property 

 101:     /// indicates ....

 102:     /// </summary>

 103:     public static void SetShouldUseTransition(DependencyObject d, bool value)

 104:     {

 105:         d.SetValue(ShouldUseTransitionProperty, value);

 106:     }

 107:  

 108:     #endregion

 109:  

 110: }

This class contains 2 attached properties CurrentState (which is a string) and a GoToStateAction which is an ICommand (It also has another property ShouldUseTransition which instructs the VSM weather to use transitions or just change the properties for the new state).

The CurrentState property will attach itself to the DepenedencyObject which is being decorated with this property and hook to its VSM (please note that the attach will crawl up the Logical Tree to find the first available VSM). This operation creates an RelayCommand that is set in the GoToStateAction attached property.

Now the interesting part happens. I created a base class for ViewModels that want to invoke states called StateBaseViewModel. Here is the code…

   1: /// <summary>

   2: /// Base view model that has a property for state changes

   3: /// </summary>

   4: public class StateBaseViewModel : BaseViewModel

   5: {

   6:     private string currentState;

   7:  

   8:     /// <summary>

   9:     /// Gets or sets the current state of the ViewModel

  10:     /// </summary>

  11:     public string CurrentState

  12:     {

  13:         get { return currentState; }

  14:         set

  15:         {

  16:             currentState = value;

  17:             RaisePropertyChanged("CurrentState");

  18:         }

  19:     }

  20:  

  21:     /// <summary>

  22:     /// Changes the CurrentState property to the spcified state

  23:     /// </summary>

  24:     public ICommand GoToStateCommand { get; protected set; }

  25:  

  26:  

  27:     /// <summary>

  28:     /// Specify a command to be fired when state changes

  29:     /// </summary>

  30:     public ICommand OnGoToState { get; set; }

  31:  

  32:  

  33:     public StateBaseViewModel()

  34:     {

  35:         GoToStateCommand = new RelayCommand(

  36:             x =>

  37:             {

  38:                 CurrentState = (string)x;

  39:                 if (OnGoToState != null && OnGoToState.CanExecute(CurrentState))

  40:                     OnGoToState.Execute(CurrentState);

  41:             },

  42:             x => !String.IsNullOrEmpty((string)x)

  43:             );

  44:     }

  45: }

This base view model has the same 2 properties of the VisualStateManagerInvoker. We can make these 2 in sync together by using standard TwoWay databinding. By doing so the VisualStateManagerInvoker will feed the View Model with a command that is hooked up to a UI element VSM and when invoked this will ask the VSM for that element to transition to the state passed as parameter.

Here is the binding for this

   1: <local:Checkout  

   2:     mvvmStateManagement:VisualStateManagerInvoker.CurrentState="{Binding CurrentState}"

   3:     mvvmStateManagement:VisualStateManagerInvoker.GoToStateAction="{Binding OnGoToState, Mode=TwoWay}" />

Assuming that the element local:Checkout has a datacontext set to a view model that is inheriting from StateBaseViewModel, you can see how the VisualStateManagerInvoker is feeding this View model a GoToStateAction by simple two way databinding.

Since this command is now ready to be used from our ViewModel we can invoke a state by simple executing the command like so.

   1: CancelCommand = new RelayCommand(x =>

   2:                 {

   3:                     GoToStateCommand.Execute("CancelState");

   4:                 });

This is super awesome isn’t it 🙂

Another cool thing about this is that you can use this trick so that you can invoke a state from a child to its parent. Lets say that you have a Window that contains a usercontrol (which has a StateBaseViewModel set as its datacontext) and a button. You want the button to show the UserControl. Ok easy Just drag and drop a GoToStateAction behavior and set its state to the state which makes the user control visible. But now lets say you have a button inside the user control and this button needs to invoke a state defined in the Window. The VSM works with namescopes thus you cannot invoke a state that is out of your namescope. BUT with the approach of uses VisualStateManagerInvoker we can do this since we can set the binding in the same XAML line that declares the usercontrol in the Window thus being in the same namescope as the Window 🙂 We can then make a normal command that executes the GoToStateCommand in out StateBaseViewModel (this example is in the sample application to Cancel the check out of the shopping list and to show the thank you message when someone checks out the shopping cart)

Please note that the same code works for Silverlight.

Conclusion

I think that by using VSM one makes the Developer Designer workflow a happier thing. Designers love VSM and I learnt to love it as well. Now that I can invoke states easily from my ViewModel. Besides that since the implementation gets the VSM instance in an attached behavior and then feeds it to the ViewModel via databinding, the ViewModel never touches the VSM thus unit testing is much easier like this.

I found this way of working with the VSM awesome… OK I still need to make it cooler but as it is right now you can just grab the code and start working without any problems…. hope it helps 😀

 

Download sample application (P.S Open this in Blend 3 to get maximum pleasure 🙂 )

(Sample application contains MVVMHelper a small library I built for MVVM. It contains loads of goodies… have a look and enjoy)

Some Astoria tips I learnt today

First of all let me start by saying that if you are doing Silverlight, you must learn Astoria, or as they call it nowadays, ADO.NET Data Services..

http://msmvps.com/blogs/theproblemsolver/archive/2009/01/06/consuming-an-ado-net-data-service-from-silverlight.aspx

In a matter of minutes you can expose data from a database in a restful service that can be consumed by Silverlight 🙂

Now here are some things I learnt today…

The first tip is How can I have the Service on 1 server and the Silverlight app on another without having Cross Domain issues…

The answer to this is this url

http://blogs.msdn.com/astoriateam/archive/2009/09/03/using-the-ado-net-data-services-silverlight-client-in-x-domain-and-out-of-browser-scenarios-i.aspx

Its important that you install the v1.5 CTP2 since by default this is not the version that comes with .NET 3.5 SP1 (Please note you also have to follow the rest of the steps… )

Another useful tip I learnt today is how to Expand a Property of a Property inside an entity (common when you have many to many relations). Example you have a Venue table that is linked to Sports with a table called VenueSportMapping. You can use XPath like syntax to load the property value.

   1: var query = from x in context.Venue.Expand("VenueSportMapping/Sport")

   2:                         select x;

Thats all I have for today… hope you find these 2 tips handy 🙂

happy coding 🙂

How to set WPF ScrollViewer VerticalOffset and Horizontal offset

Today I needed to bind to the ScrolViewer VerticalOffset and Horizontal offset to do an animation for them. Yet unfortunately you cannot do this. In order to set these properties you need to use the ScrollToVerticalOffset or ScrollToHorizontalOffset methods :S This is not very good because it means you cannot do DataBinding or animate these properties….

Well as usual I resorted to  Attached Behaviour. Basically I created 2 attached properties one for HorizontalOffset and one for VerticalOffset. These properties just call the methods ScrollToVerticalOffset or ScrollToHorizontalOffset inside the property changed handlers… yep it’s as simple as that… Here is the attached behaviour class

   1: public class ScrollViewerUtilities

   2: {

   3:     #region HorizontalOffset

   4:  

   5:     /// <summary>

   6:     /// HorizontalOffset Attached Dependency Property

   7:     /// </summary>

   8:     public static readonly DependencyProperty HorizontalOffsetProperty =

   9:         DependencyProperty.RegisterAttached("HorizontalOffset", typeof(double), typeof(ScrollViewerUtilities),

  10:             new FrameworkPropertyMetadata((double)0.0,

  11:                 new PropertyChangedCallback(OnHorizontalOffsetChanged)));

  12:  

  13:     /// <summary>

  14:     /// Gets the HorizontalOffset property.  This dependency property 

  15:     /// indicates ....

  16:     /// </summary>

  17:     public static double GetHorizontalOffset(DependencyObject d)

  18:     {

  19:         return (double)d.GetValue(HorizontalOffsetProperty);

  20:     }

  21:  

  22:     /// <summary>

  23:     /// Sets the HorizontalOffset property.  This dependency property 

  24:     /// indicates ....

  25:     /// </summary>

  26:     public static void SetHorizontalOffset(DependencyObject d, double value)

  27:     {

  28:         d.SetValue(HorizontalOffsetProperty, value);

  29:     }

  30:  

  31:     /// <summary>

  32:     /// Handles changes to the HorizontalOffset property.

  33:     /// </summary>

  34:     private static void OnHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

  35:     {

  36:         var viewer = (ScrollViewer)d;

  37:         viewer.ScrollToHorizontalOffset((double)e.NewValue);

  38:     }

  39:  

  40:     #endregion

  41:  

  42:     #region VerticalOffset

  43:  

  44:     /// <summary>

  45:     /// VerticalOffset Attached Dependency Property

  46:     /// </summary>

  47:     public static readonly DependencyProperty VerticalOffsetProperty =

  48:         DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), typeof(ScrollViewerUtilities),

  49:             new FrameworkPropertyMetadata((double)0.0,

  50:                 new PropertyChangedCallback(OnVerticalOffsetChanged)));

  51:  

  52:     /// <summary>

  53:     /// Gets the VerticalOffset property.  This dependency property 

  54:     /// indicates ....

  55:     /// </summary>

  56:     public static double GetVerticalOffset(DependencyObject d)

  57:     {

  58:         return (double)d.GetValue(VerticalOffsetProperty);

  59:     }

  60:  

  61:     /// <summary>

  62:     /// Sets the VerticalOffset property.  This dependency property 

  63:     /// indicates ....

  64:     /// </summary>

  65:     public static void SetVerticalOffset(DependencyObject d, double value)

  66:     {

  67:         d.SetValue(VerticalOffsetProperty, value);

  68:     }

  69:  

  70:     /// <summary>

  71:     /// Handles changes to the VerticalOffset property.

  72:     /// </summary>

  73:     private static void OnVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

  74:     {

  75:         var viewer = (ScrollViewer)d;

  76:         viewer.ScrollToVerticalOffset((double)e.NewValue);

  77:     }

  78:  

  79:     #endregion

  80:  

  81: }

and here is XAMl of how I use this

   1: <Grid>

   2:     <Grid.RowDefinitions>

   3:         <RowDefinition />

   4:         <RowDefinition Height="100"/>

   5:     </Grid.RowDefinitions>

   6:     <ScrollViewer x:Name="scrollViewer" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible"  >

   7:         <Border Width="9000" Height="9000"/> 

   8:     </ScrollViewer>

   9:     

  10:     <StackPanel Grid.Row="1">

  11:         <WrapPanel>

  12:             <TextBlock Text="Slider for horizontal: Value:" Margin="0,0,10,0"/>    

  13:             <TextBlock Text="{Binding ElementName=scrollViewer, Path=HorizontalOffset}"/>

  14:         </WrapPanel>

  15:         <Slider Value="{Binding ElementName=scrollViewer, Path=(local:ScrollViewerUtilities.HorizontalOffset)}" 

  16:                 Minimum="0" Maximum="9000"/>

  17:         <WrapPanel>

  18:             <TextBlock Text="Slider for vertical: Value:" Margin="0,0,10,0"/>

  19:             <TextBlock Text="{Binding ElementName=scrollViewer, Path=VerticalOffset}"/>

  20:         </WrapPanel>

  21:         <Slider Value="{Binding ElementName=scrollViewer, Path=(local:ScrollViewerUtilities.VerticalOffset)}" 

  22:                 Minimum="0" Maximum="9000"/>

  23:         

  24:         <WrapPanel>

  25:             <TextBlock Text="Animate scroll" Margin="0,0,10,0"/>

  26:             <Button Content="Do it">

  27:                 <Button.Triggers>

  28:                     <EventTrigger RoutedEvent="Button.Click">

  29:                         <BeginStoryboard>

  30:                             <Storyboard>

  31:                                 <DoubleAnimation Storyboard.TargetName="scrollViewer" 

  32:                                          Storyboard.TargetProperty="(local:ScrollViewerUtilities.VerticalOffset)"

  33:                                          Duration="0:0:1" DecelerationRatio="1.0" To="8000"/>

  34:                             </Storyboard>

  35:                         </BeginStoryboard>

  36:                     </EventTrigger>

  37:                 </Button.Triggers>

  38:             </Button>

  39:         </WrapPanel>

  40:     </StackPanel>

  41: </Grid>

Download the sample app I built for this…

Article revisited: MVVM + M (implementing a Fly Weight TreeView)

Ages ago I wrote an article to introduce an idea that I had for the Mediator pattern to work with MVVM (at that time MVVM was still in the being of its age so I didn’t even call it View Model I called it Controller).

Today I was preparing for a Demo that I will be doing in Poland and I thought to revisit this article and refactor it with the new methods that I discovered over the last year.

What’s new in the new and exciting in the new version.

>> Well for starters I am using a new and improved version of the Mediator. The new version of the Mediator API is much more user friendly. It support Generics and it also eliminates the need to have interfaces implemented for you ViewModel. Instead of implementing an interface and have a switch for the message type now you simple register a message to an Action delegate. The Action delegate can be of a generic type so that you don’t even have to cast the argument. You can read more on this over here.

>> This version also uses Service Locator and the concept of ViewModel Loaders that I introduced in this article.

>> It also uses attached behaviours for the TreeView instead of a ViewModel registering to routed events of the treeview through the EventManager. This is much better! Event Manager registration of event inside a ViewModel can be very dangerous and also makes the ViewModel dirty with references to UI elements. Yet at that time it was an approach that I thought was best, as I said those days were just when View Model concept was emerging…

It’s amazing what I have learnt in the last year and how much MVVM evolved!

Download the source code and have a look for yourself…. Compare the 2 versions and see how much better we WPF developers can today use MVVM 🙂

Animating width and height when they are Double.NaN

A common problem in WPF when doing animation to width and height is that you cannot animate these properties (or any other properties of type double) if they are by default unset.

Here is a snippet that shows the code that would raise this kind of exception

   1: <Border Background="Red" HorizontalAlignment="Center" VerticalAlignment="Center">

   2:    <TextBlock Text="CLICK ME" VerticalAlignment="Center" HorizontalAlignment="Center"/>

   3:    <Border.Triggers>

   4:        <EventTrigger RoutedEvent="UIElement.MouseDown">

   5:            <BeginStoryboard>

   6:                <Storyboard>

   7:                    <DoubleAnimation Storyboard.TargetProperty="Height" To="300"/>

   8:                </Storyboard>

   9:            </BeginStoryboard>

  10:        </EventTrigger>

  11:    </Border.Triggers>

  12: </Border>

When you try to do this you get an exception like this one

>> Cannot animate the ‘Height’ property on a ‘System.Windows.Controls.Border’ using a ‘System.Windows.Media.Animation.DoubleAnimation’. For details see the inner exception.

and same for Width.

What I do in order to achieve the same behaviour without the need of setting a default width and height is to use a Scale Transform instead. Here is a snippet to get the same behaviour as the XAML above to animate the height

   1: <Border Background="Red" HorizontalAlignment="Center" VerticalAlignment="Center">

   2:    <TextBlock Text="CLICK ME" VerticalAlignment="Center" HorizontalAlignment="Center"/>

   3:    <Border.RenderTransform>

   4:        <ScaleTransform ScaleX="1" ScaleY="1" />

   5:    </Border.RenderTransform>

   6:    <Border.Triggers>

   7:        <EventTrigger RoutedEvent="UIElement.MouseDown">

   8:            <BeginStoryboard>

   9:                <Storyboard>

  10:                    <DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)" To="2"/>

  11:                </Storyboard>

  12:            </BeginStoryboard>

  13:        </EventTrigger>

  14:    </Border.Triggers>

  15: </Border>

Please note that there is a catch here. By using scale transform everything inside the actual control will be scaled. So if that is not what you want then you have a problem.

Yet of course there are solutions…. One of the solutions is to have an attached property to set the Height for you when the control is loaded. This can be achieved by setting the Height/Width to the ActualHeight/ActualWidth. Here is an attached property that I use in such cases.

   1: #region SetHeightToActual

   2:  

   3: /// <summary>

   4: /// SetHeightToActual Attached Dependency Property

   5: /// </summary>

   6: public static readonly DependencyProperty SetHeightToActualProperty =

   7:     DependencyProperty.RegisterAttached("SetHeightToActual", typeof(bool), typeof(WidthHeightBehaviour),

   8:         new FrameworkPropertyMetadata((bool)false,

   9:             new PropertyChangedCallback(OnSetHeightToActualChanged)));

  10:  

  11: /// <summary>

  12: /// Gets the SetHeightToActual property.  This dependency property 

  13: /// indicates ....

  14: /// </summary>

  15: public static bool GetSetHeightToActual(DependencyObject d)

  16: {

  17:     return (bool)d.GetValue(SetHeightToActualProperty);

  18: }

  19:  

  20: /// <summary>

  21: /// Sets the SetHeightToActual property.  This dependency property 

  22: /// indicates ....

  23: /// </summary>

  24: public static void SetSetHeightToActual(DependencyObject d, bool value)

  25: {

  26:     d.SetValue(SetHeightToActualProperty, value);

  27: }

  28:  

  29: /// <summary>

  30: /// Handles changes to the SetHeightToActual property.

  31: /// </summary>

  32: private static void OnSetHeightToActualChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

  33: {

  34:     if ((bool)e.NewValue)

  35:     {

  36:         var element = (FrameworkElement)d;

  37:         RoutedEventHandler handler = null;

  38:         handler = delegate

  39:         {

  40:             element.Height = element.ActualHeight;

  41:             element.Loaded -= handler;

  42:         };

  43:         element.Loaded += handler;

  44:     }

  45: }

  46:  

  47: #endregion

And here is the XAML where I am using the attached behaviour. It is nearly seamless

   1: <Border Background="Red" HorizontalAlignment="Center" VerticalAlignment="Center" local:WidthHeightBehaviour.SetHeightToActual="True">

   2:    <TextBlock Text="CLICK ME" VerticalAlignment="Center" HorizontalAlignment="Center"/>

   3:    <Border.Triggers>

   4:        <EventTrigger RoutedEvent="UIElement.MouseDown">

   5:            <BeginStoryboard>

   6:                <Storyboard>

   7:                    <DoubleAnimation Storyboard.TargetProperty="Height" To="300"/>

   8:                </Storyboard>

   9:            </BeginStoryboard>

  10:        </EventTrigger>

  11:    </Border.Triggers>

  12: </Border>

You can do the same thing for the Width or any other property of this kind (for example I use this technique also for Center property of ScatterViewItems in Surface development).

Hope this tip/trick helps 🙂

Happy coding