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

Service Locator in MVVM

While doing MVVM one of the common problems to solve is to have the ViewModel consume entities that are “replaceable”. Let me give you an example so that you can better understand what I mean by “replaceable“. Let’s say you have a ViewModel that is using a DataAccess entity to get some data from a data store. You want to be able replace the DataAccess entity so that you can mock this entity for unit testing. Besides this you want to also be able to have some sample data while at design time. And not to forget, when at runtime you want the data access to connects to the database or whatever data store you are using.

In order to do solve this problem I use the ServiceLocator pattern. The Service Locator pattern is very simple. You have a RegisterService method where you register the instance of the service you want to provide and a GetService method which you would use to get the service you want.

Here is the signature of both methods

   1: public T GetService<T>()

   2:  

   3: public bool RegisterService<T>(T service)

And here is how to use them in code

   1: //get the data access service

   2: var dataAccess = GetService<IPeopleDataAccess>();

   3:  

   4: //Register the data access service

   5: vm.ServiceLocator.RegisterService<IPeopleDataAccess>(new PeopleDataAccess());

So for example to test the the ViewModel I can write a unit test like this

   1: MainViewModel viewModel = new MainViewModel();

   2: viewModel.ServiceLocator.RegisterService<IPeopleDataAccess>(new PeopleDataAccessMock());

   3:  

   4: Assert.AreEqual(viewModel.People.Count, PeopleDataAccessMock.PeopleCount,

   5:    "Invalid number of People returned");

   6: Assert.AreEqual(viewModel.People[0].Name, PeopleDataAccessMock.FirstPersonName,

   7:    "Invalid item in people list");

   8: Assert.AreEqual(viewModel.People[0].Surname, PeopleDataAccessMock.FirstPersonSurname,

   9:    "Invalid item in people list");

So basically in this unit test I am just creating a mock object and testing that my ViewModel is exposing the data from the data access (which is mocked so the data returned by this data access is known in the test context)

This is all cool but now how can I use this in WPF and MVVM. So the first question that people ask is how do I create the ViewModel and set it as the DataContext. And also who is responsible of assigning the services that the ViewModel will consume. In order to do this I use AttachedBehaviour and the Factory design pattern.

I created a simple attached property that accepts a type of a Factory that is responsible for creating the ViewModel and register whatever services it needs. The attached property is very simple, here is the code for it

   1: public class ViewModelLoader

   2: {

   3:     #region FactoryType

   4:  

   5:     /// <summary>

   6:     /// FactoryType Attached Dependency Property

   7:     /// </summary>

   8:     public static readonly DependencyProperty FactoryTypeProperty =

   9:         DependencyProperty.RegisterAttached("FactoryType", typeof(Type), typeof(ViewModelLoader),

  10:             new FrameworkPropertyMetadata((Type)null,

  11:                 new PropertyChangedCallback(OnFactoryTypeChanged)));

  12:  

  13:     /// <summary>

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

  15:     /// indicates ....

  16:     /// </summary>

  17:     public static Type GetFactoryType(DependencyObject d)

  18:     {

  19:         return (Type)d.GetValue(FactoryTypeProperty);

  20:     }

  21:  

  22:     /// <summary>

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

  24:     /// indicates ....

  25:     /// </summary>

  26:     public static void SetFactoryType(DependencyObject d, Type value)

  27:     {

  28:         d.SetValue(FactoryTypeProperty, value);

  29:     }

  30:  

  31:     /// <summary>

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

  33:     /// </summary>

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

  35:     {

  36:         FrameworkElement element = (FrameworkElement)d;

  37:         IFactory factory = Activator.CreateInstance( GetFactoryType(d) ) as IFactory;

  38:         if (factory == null)

  39:             throw new InvalidOperationException("You have to specify a type that inherits from IFactory");

  40:         element.DataContext = factory.CreateViewModel(d);

  41:     }

  42:  

  43:     #endregion

  44:  

  45: }

and you can use this in XAML like so

   1: <Window x:Class="ServiceLocatorSample.Main"

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

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

   4:     xmlns:vm="clr-namespace:MVVMHelper.Factory;assembly=MVVMHelper"

   5:     xmlns:fac="clr-namespace:ServiceLocatorSample.ViewModels.Factories"

   6:     Title="Main" Height="300" Width="300" vm:ViewModelLoader.FactoryType="{x:Type fac:MainViewModelFactory}">

Usually in the implementation of the factory I would check if the current state is at design time or runtime and accordingly register different services. Something like this

   1: public class MainViewModelFactory : IFactory

   2: {

   3:    public object CreateViewModel(DependencyObject sender)

   4:    {

   5:        var vm = new MainViewModel();

   6:        if (Designer.IsDesignMode)

   7:            vm.ServiceLocator.RegisterService<IPeopleDataAccess>(new DesignTimeData.DesignTimePeopleDataAccess());

   8:        else

   9:            vm.ServiceLocator.RegisterService<IPeopleDataAccess>(new PeopleDataAccess());

  10:        return vm;

  11:    }

  12: }

So with this factory at design time I would get Design time data showing in my designer but as soon as I run the app the actual data access (the real one that connects to the database) gets injected.

That’s it for today. Download the sample project and you will have a better idea of how all this works. Any questions or comments please let me know, I will be more than happy to answer :)

P.S In the sample I have the full MVVMHelper assembly that I use in my everyday work with MVVM so you will also have stuff like Mediator and other things that I will be blogging about very soon :)

Download the sample project

Playing with Shaders: Creating a water effect

Lately I’ve been looking at a really cool project on Codeplex for Pixel Shaders. The set of shaders in this library is awsome and really easy to use in you application….

All you need to do to consume any Shader is add a reference to the WPFShaderEffectLibrary class library and you can start using the shaders in XAML.What is really important is that you install the Shaders Build Task before trying to build the shader library (if you just add a reference to the ready build dlls you don’t even need to do this).

 

Water

So let’s have a look at how we can use shaders to simulate water on screen.

This is very easy all we need is a ripple shader effect. so something like this

   1: <Window.Resources>

   2:  

   3:    <Storyboard x:Key="waterAnimMain">

   4:        <DoubleAnimation Storyboard.TargetName="rippleMain" Storyboard.TargetProperty="Phase" To="0" From="10" Duration="0:0:2.0"  FillBehavior="Stop" />

   5:        <DoubleAnimation Storyboard.TargetName="rippleMain" Storyboard.TargetProperty="Amplitude" To="0" From="0.6" Duration="0:0:2.0"  FillBehavior="HoldEnd" />

   6:        <DoubleAnimation Storyboard.TargetName="rippleMain" Storyboard.TargetProperty="Frequency" To="0" From="30" Duration="0:0:2.5" FillBehavior="HoldEnd" />

   7:    </Storyboard>

   8:  

   9: </Window.Resources>

  10: <Grid Background="Transparent" >

  11:  

  12:    <Border>

  13:        <Border.Background>

  14:            <LinearGradientBrush EndPoint="0.93,0.925" StartPoint="0.094,0.125">

  15:                <GradientStop Color="#FF272788" Offset="0.112"/>

  16:                <GradientStop Color="#FF090916" Offset="0.721"/>

  17:                <GradientStop Color="#FE222267" Offset="0.28"/>

  18:                <GradientStop Color="#FE131339" Offset="0.453"/>

  19:                <GradientStop Color="#FF04040A" Offset="0.974"/>

  20:            </LinearGradientBrush>

  21:        </Border.Background>

  22:    

  23:    </Border>

  24:  

  25: </Grid>

  26:  

  27: <Window.Effect>

  28:    <shader:RippleEffect Amplitude="0" Frequency="0" Phase="0" x:Name="rippleMain"  />

  29: </Window.Effect>

This is our Shader

   1: <shader:RippleEffect Amplitude="0" Frequency="0" Phase="0" x:Name="rippleMain"  />

And we animate this shader like so to make the effect of water

   1: <Storyboard x:Key="waterAnimMain">

   2:      <DoubleAnimation Storyboard.TargetName="rippleMain" Storyboard.TargetProperty="Phase" To="0" From="10" Duration="0:0:2.0"  FillBehavior="Stop" />

   3:      <DoubleAnimation Storyboard.TargetName="rippleMain" Storyboard.TargetProperty="Amplitude" To="0" From="0.6" Duration="0:0:2.0"  FillBehavior="HoldEnd" />

   4:      <DoubleAnimation Storyboard.TargetName="rippleMain" Storyboard.TargetProperty="Frequency" To="0" From="30" Duration="0:0:2.5" FillBehavior="HoldEnd" />

   5:  </Storyboard>

We invoke this animation by having a DispatcherTimer trigger the animation every now and then and changing the Center property of the Shader to a random point from 0 to 1.

This already gets us very close but it still does not feel like real water. The trick is to animate to ripple effects at the same time. This will make the ripple effects expand together and thus making the control which has the shader applied look like water. Yet the problem is that you can only apply ONE shader per control. BUT you can have another shader on the parent control and that would still apply the shader on all children (I explain this in this article).

   1: <Window.Resources>

   2:  

   3:     <Storyboard x:Key="waterAnimMain">

   4:         <DoubleAnimation Storyboard.TargetName="rippleMain" Storyboard.TargetProperty="Phase" To="0" From="10" Duration="0:0:2.0"  FillBehavior="Stop" />

   5:         <DoubleAnimation Storyboard.TargetName="rippleMain" Storyboard.TargetProperty="Amplitude" To="0" From="0.6" Duration="0:0:2.0"  FillBehavior="HoldEnd" />

   6:         <DoubleAnimation Storyboard.TargetName="rippleMain" Storyboard.TargetProperty="Frequency" To="0" From="30" Duration="0:0:2.5" FillBehavior="HoldEnd" />

   7:     </Storyboard>

   8:  

   9:     <Storyboard x:Key="waterAnimSub">

  10:         <DoubleAnimation Storyboard.TargetName="rippleSub" Storyboard.TargetProperty="Phase" To="0" From="10" Duration="0:0:2.0"  FillBehavior="Stop" />

  11:         <DoubleAnimation Storyboard.TargetName="rippleSub" Storyboard.TargetProperty="Amplitude" To="0" From="0.6" Duration="0:0:2.0"  FillBehavior="HoldEnd" />

  12:         <DoubleAnimation Storyboard.TargetName="rippleSub" Storyboard.TargetProperty="Frequency" To="0" From="30" Duration="0:0:2.5" FillBehavior="HoldEnd" />

  13:     </Storyboard>

  14:  

  15: </Window.Resources>

  16: <Grid Background="Transparent" >

  17:  

  18:     <Border>

  19:         <Border.Background>

  20:             <LinearGradientBrush EndPoint="0.93,0.925" StartPoint="0.094,0.125">

  21:                 <GradientStop Color="#FF272788" Offset="0.112"/>

  22:                 <GradientStop Color="#FF090916" Offset="0.721"/>

  23:                 <GradientStop Color="#FE222267" Offset="0.28"/>

  24:                 <GradientStop Color="#FE131339" Offset="0.453"/>

  25:                 <GradientStop Color="#FF04040A" Offset="0.974"/>

  26:             </LinearGradientBrush>

  27:         </Border.Background>

  28:         <Border.Effect>

  29:             <shader:RippleEffect Amplitude="0" Frequency="0" Phase="0" x:Name="ripple" Center="{Binding ElementName=main, Path=(local:MouseBehaviour.LastMouseUp)}" />

  30:         </Border.Effect>

  31:     </Border>

  32:  

  33:     <Grid.Triggers>

  34:  

  35:         <EventTrigger RoutedEvent="UIElement.MouseUp">

  36:             <BeginStoryboard Storyboard="{StaticResource waterAnim}"/>

  37:             <BeginStoryboard Storyboard="{StaticResource waterAnimMain}"/>

  38:         </EventTrigger>

  39:     </Grid.Triggers>

  40:  

  41:     <Grid.Effect>

  42:         <shader:RippleEffect Amplitude="0" Frequency="0" Phase="0" x:Name="rippleSub"  />

  43:     </Grid.Effect>

  44:  

  45: </Grid>

  46:  

  47: <Window.Effect>

  48:     <shader:RippleEffect Amplitude="0" Frequency="0" Phase="0" x:Name="rippleMain"  />

  49: </Window.Effect>

And that’s it. Now we have a perfect water look thanks to the Codeplex Pixel Shader library :)

I created a sample app that shows all this. The app also has another feature so that you can touch the water by using the mouse and the water would ripple from the point you touch (of course this is with Behaviours so that you can even reuse it :D )

Happy coding :D

DOWNLOAD SOURCE CODE

Sync Multi Select Listbox with ViewModel

Today one of my colleagues at Infusion asked me how he could sync up the selection of a ListBox with his ViewModel. WPF supports already single mode selection via the ICollectionView yet when it comes to MultiSelect there is no out of the box support in WPF.

Attached Properties to the rescue ….. :)

I quickly when in my VS and wrote up a simple Attached property that hooks to the SelectionChanged event of the ListBox and populates a list of selected items to the ViewModel.

This is how the attached property looks like

   1: #region SelectedItems

   2:  

   3: /// <summary>

   4: /// SelectedItems Attached Dependency Property

   5: /// </summary>

   6: public static readonly DependencyProperty SelectedItemsProperty =

   7:     DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), typeof(ListBoxHelper),

   8:         new FrameworkPropertyMetadata((IList)null,

   9:             new PropertyChangedCallback(OnSelectedItemsChanged)));

  10:  

  11: /// <summary>

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

  13: /// indicates ....

  14: /// </summary>

  15: public static IList GetSelectedItems(DependencyObject d)

  16: {

  17:     return (IList)d.GetValue(SelectedItemsProperty);

  18: }

  19:  

  20: /// <summary>

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

  22: /// indicates ....

  23: /// </summary>

  24: public static void SetSelectedItems(DependencyObject d, IList value)

  25: {

  26:     d.SetValue(SelectedItemsProperty, value);

  27: }

  28:  

  29: /// <summary>

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

  31: /// </summary>

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

  33: {

  34:     var listBox = (ListBox)d;

  35:     ReSetSelectedItems(listBox);

  36:     listBox.SelectionChanged += delegate

  37:     {

  38:         ReSetSelectedItems(listBox);

  39:     };

  40: }

  41:  

  42: #endregion

  43:  

  44: private static void ReSetSelectedItems(ListBox listBox)

  45: {

  46:     IList selectedItems = GetSelectedItems(listBox);

  47:     selectedItems.Clear();

  48:     if (listBox.SelectedItems != null)

  49:     {

  50:         foreach (var item in listBox.SelectedItems)

  51:             selectedItems.Add(item);

  52:     }

  53: }

and here is how you would use it in the XAML

   1: <ListBox ItemsSource="{Binding MyData}" Grid.Column="1" local:ListBoxHelper.SelectedItems="{Binding SelectedData}"

   2:                  SelectionMode="Extended"/>

As you can see all you have to set is the List you want to populate in the ViewModel and the rest is taken care of by the Attached Property.

Please Note: This code was implemented quickly without any testing to prove an implementation idea, so please do review it before putting it in production :)

Download the source code

[MVVM + Mediator + ACB = cool WPF App] – The MVVM

The Model View ViewModel is quite a hot subject right now in the WPF community. If you never read about MVVM I suggest that you read the following before you continue reading

- Introduction to Model/View/ViewModel pattern for building WPF apps by John Gossman (MVVM daddy)

- WPF & Silverlight Line of Business UI Design Pattern by Karl Shifflett

- WPF Apps With The Model-View-ViewModel Design Pattern by Josh Smith

 

MVVM in my sample app

Let me start by showing you a class diagram of the application structure

Desktop

As you can see in the image above we have 3 layers. We have our Views, the ViewModels and the Models. (Please note that you can have n Tiers yet I am focusing just on 2 Tiers here, View and ViewModel….)

The View

The view is the “component” that renders the data on screen. This should be done all in XAML and not in C#. Why? Well UIs are much better built in a declarative fashion instead of an imperative one.

The View can be developed by a designer by using tools such as Blend and should not require any need from a developer. In the View the designer should express his artistic creativeness without any constrains from the developers.

Besides this when you put code in the View, this code is super hard to Unit test. From experiance I must say that 99% of the code written in the UI layer is never tested.

Ok so the designer sets the colors of the buttons etc… BUT!!!!

A - what about the data?  From where can the designer get the data without having C# knowledge?
B – what about actions/events? How can a designer specify that when the button is clicked something should happen?

Well my friends that is the power of the WPF Databinding and the MVVM!

The ViewModel

The ViewModel is just a simple class (That has no coupling with the View and 100% unit testable). The ViewModel exposes data that the View can use to render the UI. Besides this the ViewModel also has Commands that the View can use to invoke actions. I will demo 2 pages that I created in the Sample App that explain how the ViewModel does this job.

A – what about the data?

 DataBinding

To show you how the view renders data exposed by the ViewModel we will take the example in the screen shot above.

The ViewModel involved here is called ProjectListViewModel and the View is called ProjectList.xaml

The ViewModel exposes the data via a property called Projects. The property is shown below

   1: ObservableCollection<WPFDisciples.Backend.ProjectDetails> projects

   2:     = new ObservableCollection<WPFDisciples.Backend.ProjectDetails>();

   3: public ObservableCollection<WPFDisciples.Backend.ProjectDetails> Projects

   4: {

   5:     get { return projects; }

   6: }

As you can see this is simply a normal CLR property (not a DependencyProperty ). In this case the real magic is not in the property as such but in the type of Collection. Since the property exposes an ObservableCollection<T>, the databinding engine will listen to collection changed notifications and update the rendered data according.

This is how we bind to the data in the View’s XAML

   1: <ListView ItemsSource="{Binding Projects}"

In this XAML we are doing List binding. We are specifying to the ListView that it should bind to the Projects property. The question is the Projects property of what object?

By default the source of a Binding is the DataContext of the element. In this case the DataContext will be the ViewModel. We specify that in the constructor of the View. There are many other nicer ways of doing this initialization of ViewModel in the View such as by using Onyx(this is a super cool WPF project!!!!! you must try it) or Dependency injection (such as in PRISM)

   1: public ProjectList()

   2:         {

   3:             InitializeComponent();

   4: 

   5:             var viewModel = new ProjectListViewModel(Dispatcher);
   6:             DataContext = viewModel;

   7:         }

B – what about actions/events?

So let’s say you have a button and you want something to happen when the user clicks the button. Well the approach that we have been using in .Net is events. So a button would have a Click event and you would register an event handler for the event. Yet is this the right approach? Can a designer do this? Can you easily unit test such a method? Well I would say not really or better not easily…

A much better method has been introduced in WPF, the Commands. With commands you can delegate the work (such as a Click event) to the ViewModel. By doing so, the Designer can just specify what command to use for a button and viola he is done. Besides that the ViewModel can be unit tested much easier.

enter data

The example I picked from the sample app is the Save button to add a new Project. This can be found ProjectDetailsViewModel.cs

Here is the code that I used to expose the Command

/// <summary>
/// Gets a Command to save the current project
/// </summary>
public SimpleCommand SaveProject { get; private set; }

Where SimpleCommand is a class that implements the ICommand interface. For more info on this visit this post.

and here is the code for the Command.

SaveProject = new SimpleCommand
            {
                ExecuteDelegate = Save,
                //Can execute only if there are no errors
                CanExecuteDelegate = x => String.IsNullOrEmpty(Project.Error)
            };

Conclusion

This article should have given you a basic idea of how the M V VM works… Next post will discuss how to overcome some of the problems with MVVM. I will show you how you have to start thinking in databinding so that you implement MVVM in a proper way.

DOWNLOAD SAMPLE APP HERE

[MVVM + Mediator + ACB = cool WPF App] – Intro

Finally I managed to spare some time and build a WPF sample application to showcase the use of MVVM + Mediator and also how AttachedCommandBehaviours can be used to further reduce (or better eliminate) C# code in XAML code behind files. I am also using one of my favorite WPF libraries FluidKit. In the app I create my own 3D transition for the FluidKit TransitionPresenter (I will be posting a whole post on this).

I will be posting at least 4 posts

- MVVM

- MVVM and the Mediator pattern

- FluidKit CoverFlow and FluidKit TransitionPresenter

- Using AttachedCommandBehaviours

Here are some teaser screenshots of the application in action :)

Screen1 Screen2

Screen3 Screen4

 

Setup of application environment

This application uses a SQL Database so you will need an instance of SqlServer 2005 running (you can use SqlServer Express).

I packaged the database as a backup so all you need to do is restore the database from the SqlServer Management Studio Express (this is your easiest option). If you don’t have this I suggest you download it, it’s free.

To restore the database file (WPFDisciplesDB.bak) follow these steps

- First of all download the database file from here.

- Right click on the Databases folder in the SQL Server Management Studio Express and select Restore database

Step 1

This will open a dialog for you. In the Restore Database dialog enter a name for the database in the “To database” text field > Select “From device” radio button and browse for the WPFDisciples.bak that you downloaded. The file will appear in the list. Tick the checkbox (which is un checked by default) and press ok.

Step 2 

Now that we have our database set up all we need to do is specify in the app.config the connection string of the new database and we are done.

Stayed tuned because this should be real fun :)

aaaa I nearly forgot… The data in the database is not the full version… I will add more projects from the mighty WPF Disciples as time goes by…. Will continue updating the download link here (and put a comment or something to show you that I updated the db version)

Download Full Source Code from HERE

Just in case you missed it, here is a copy of the database

Using the WPF Web browser control in a ToolTip

While writing a small app that I will be publishing here, I stumbled upon a strange issue. I was trying to put the WPF WebBrowser control inside a Tooltip yet the WebBrowser was not appearing on the screen. After an hour of debugging and trying out different things I found this WPF Forum thread that solved my issue… The problem has something to do with the WebBrowser being a native control and not a pure WPF control (so you are actually using an HwndHost in order to show it in a WPF app).  Also you might want to have a look at this blog post, it’s from the answerer of the forum post. Anyway, I just thought to share this with who ever is encountering this problem…..

Now I’m headed back coding my new project… should be cool, will post it shortly hopefully :)

AttachedCommandBehavior aka ACB

Introduction

The WPF Commands are really a cool and powerful tool that really help when you are trying to separate concerns by using patterns such as M-V-VM. If you haven’t had a look at my previous post on the ICommand I suggest that you do that before reading this post.

The only thing that I see a bit limited is the fact that you can use Commands only when a control implements the ICommandSource (such as ButtonBase etc). Well to say the truth you can still use commands if a Control does not implement ICommandSource but you have to do some plumbing yourself. Another problem that I see is that when a control implements the ICommandSource you are bound to the fact that the command will get executed according to the event being hooked up  in the control implementation of ICommandSource, for example in case of a Button the Command would be executed when the Click event is raised. But what if you don’t want to execute a command when the Click event is fired, what if you want a command to be fired when the MouseRightButtonDown… One of my favorite WPF gurus, John Gossman blogged on this, read his post here.

I really love this approach yet you have to create an AttachedProperty for every different event you want to hook to.

It would be nice if you could supply the name of an Event in an AttachedProperty and the rest is done for you, i.e calling the Command when the event is fired… something like this….

   1: <Border Background="Aqua" 
   2:     local:CommandBehavior.Event="MouseDown" 
   3:     local:CommandBehavior.Command="{Binding SomeCommand}"
   4:     local:CommandBehavior.CommandParameter="{Binding}"/>

What are the benefits of such an approach

1. Hook a Command to any Event and any control
2. You can change the event to which a command is hooked at runtime
3. You can Databind the Command, the CommandParameter and also the Event which will execute your Command (This is shown in the demo by binding the event to a combobox populated with event names.

This solution would not only let the ViewModel control what is shown in the View but also control the Behavior of the UI if needed.

With this the ViewModel now has the power to control also the behavior of the the UI !

And here comes the AttachedCommandBehavior

I had some spare time to play around with this and I wrote a small prototype for this. My implementation consists of a 3 Attached properties where the user can specify the Event, Command and CommandParameter. Once these properties are set the hooking of the event is done automatically so that when the specified event is fired the Command is called. Here is a breakdown of the classes I created…

ACB

CommandBehavior

Defines the Attached properties to be used on a control that need to hook an event to a Command.

Properties you will be using to set up a CommandBehavior

- BehaviorProperty
This is a private property that is used internal to create the CommandBehaviorBinding

- Event
This is an attached property that stores the Event name (as a string) for the Event you want to hook.

- Command
This is an attached property that stores the instance of the ICommand you want to execute when the event (specified in the Event property) is raised

- CommandParameter
This is an attached property that stores the object that you want to pass as parameter to the Command being executed

CommandBehaviorBinding

Defines the binding between an event and a command. This entity is also responsible of executing the command when the event is raised

EventHandlerGenerator

Static class that is able to create a method at runtime that has the same signature as the EventHandlerType of the Event so that we can register to any kind of event. PLEASE NOTE: This uses Reflection and also DynamicMethod which construct the IL for the event handler at runtime!

 

 

 

 

The code is very simple. All we are doing here is to create an event handler at runtime that has the same signature as the Event type. The EventHandler that we create on runtime calls a method of the CommandBehaviorBinding that executes the Command. By using reflection we get the EventInfo of the EventName set in the Attached property and hook the EventHandler we created at runtime to the Event. That’s basically it.

I think the best thing to do here is to have a look at the source code I provided in this post and see how it all works out.

Using AttachedCommandBehavior

You can specify the event name and the Command by doing something like this

   1: <Border Background="Aqua" Width="300" Margin="0,0,10,0" Height="25"
   2:         local:CommandBehavior.Event="MouseDown" 
   3:         local:CommandBehavior.Command="{Binding SomeCommand}"
   4:         local:CommandBehavior.CommandParameter="{Binding}" />

Here we are stating that when the MouseDown event is raised on the Border the SomeCommand should execute. Simple enough…

But we can do much more… We can also make the event dynamic…. something like this…

   1: <WrapPanel>
   2:     <Border Background="Aqua" Width="300" Margin="0,0,10,0" Height="25"
   3:             local:CommandBehavior.Event="{Binding ElementName=events1, Path=SelectedItem}" 
   4:             local:CommandBehavior.Command="{Binding SomeCommand}"
   5:             local:CommandBehavior.CommandParameter="{Binding ElementName=events1, Path=SelectedItem}"
   6:             />
   7:     <ComboBox ItemsSource="{Binding Events}" MinWidth="150" SelectedIndex="1" x:Name="events1"/>
   8: </WrapPanel>

So here what we are doing is bind the Event attached property to the selected item in the ComboBox (The combobox is populated with a list of Event names that the border exposes). So when the user changed the selection of the ComboBox the Command will start being executed when the newly selected event is raised, which CommandBinding dynamic :)

Limitations

- You can only hook to Events that have a Delegate of type void (for example EventHandler). I did this by design not to over complicate the generation of the dynmaic EventHandler + because most events for controls are all void.

- This solution uses Reflection so it cannot be used in XBAPs because of the security restrictions there are in XBAPs

Conclusion

This is just a prototype that I have built in a couple of hours… nothing really fancy… I did not do a lot of testing on this so please keep that in mind if you are gonna use this in a production environment. I really like this solution because it is really flexible and makes the use of Commands more easy for any kind of Control and any kind of Event! No more code behind to hook up events :D

One thing I did not add is the support for the CanExecute. I was not sure if it really makes sense in this context… Yet if you want to add it, it’s really easy all you have to do is handle the Command’s CanExecuteChanged event and call the CanExecute there :)

Hope you like this… Looking forward to hear feedback :)

 

Download the source code here

kick it on DotNetKicks.com

Avoiding CommandBinding in the XAML Code Behind files

Yesterday I got a very good question from a colleague. Basically we were discussing the M-V-VM pattern and how it makes your XAML code behind much cleaner + your application more testable. The only thing that was annoying him was the fact that he had to do the command binding and delegate the work to the ViewModel . So he asked me, “Is there a way how I can remove the Command Binding from my code behind as well?”. What he was referring to, was the hooking of Commands to the ViewModel, which would look something like this

   1: CommandBindings.Add(
   2:     new CommandBinding(Commands.Search,
   3:     (x, e) => vm.Search(),
   4:     (x, e) => e.CanExecute = vm.CanSearch())
   5:     );

And the answer is, of course you can! After all, is there something you cannot do with the mighty WPF :P

So how can we achieve this? We have to create a class that implements the ICommand interface. Here is how the ICommand interface looks like.

   1: public interface ICommand
   2: {
   3:     event EventHandler CanExecuteChanged;
   4:  
   5:     bool CanExecute(object parameter);
   6:  
   7:     void Execute(object parameter);
   8: }

Very simple isn’t it! Here is the MSDN description of the methods of this interface

ms616874.pubmethod(en-us,VS.90).gif
CanExecute
Defines the method that determines whether the command can execute in its current state.

ms616874.pubmethod(en-us,VS.90).gif
Execute
Defines the method to be called when the command is invoked.

ms616874.pubevent(en-us,VS.90).gif
CanExecuteChanged
Occurs when changes occur that affect whether or not the command should execute.

So in the CanExecute we have to put the logic that checks if we can execute the command and in the Execute we put the logic that executes the command…. but what about the CanExecuteChanged event? Well here we have to hook up to the Command System. Here is a simple implementation of the ICommand.

   1: public class SearchCommand : ICommand
   2: {
   3:     ViewModel viewModel;
   4:     public SearchCommand(ViewModel viewModel)
   5:     {
   6:         this.viewModel = viewModel;
   7:     }
   8:  
   9:     #region ICommand Members
  10:  
  11:     public bool CanExecute(object parameter)
  12:     {
  13:         return !String.IsNullOrEmpty(viewModel.SearchText);
  14:     }
  15:  
  16:     public event EventHandler CanExecuteChanged
  17:     {
  18:         add { CommandManager.RequerySuggested += value; }
  19:         remove { CommandManager.RequerySuggested -= value; }
  20:     }
  21:  
  22:     public void Execute(object parameter)
  23:     {
  24:         viewModel.MyDataView.Filter = x => ((Person)x).Name.Contains(viewModel.SearchText);
  25:     }
  26:  
  27:     #endregion
  28: }

  As you can see in order to hook up to the WPF command system we have to override the default behavior of the event and register to the CommandManager.RequerySuggested like so

   1: public event EventHandler CanExecuteChanged
   2: {
   3:     add { CommandManager.RequerySuggested += value; }
   4:     remove { CommandManager.RequerySuggested -= value; }
   5: }

This is very important because by doing so the CanExecute method will be called when ever there is focus changed, user input etc…

Once you have a class that implements the ICommand you can expose that class in your ViewModel and databind to it in the Command property of the control you want to hook up the command to like so

   1: ViewModel property
   2: /// <summary>
   3: /// Return an ICommand that can execute the search
   4: /// </summary>
   5: public ICommand SearchByNameCommand
   6: {
   7:     get { return searchByNameCommand; }
   8: }
   9:  
  10: XAML to hook to that command
  11: <Button Command="{Binding SearchByNameCommand}" Content="Search" />

And that’s it… No more command bindings to hook to the Command in the code behind of the XAML file! This is very cool but now I guess the next question would be, so we actually have to create a class and implement an ICommand every time??

Well the answer is HELL NO…. What I do is create a class that does all the stuff for me and then I pass a delegate for the CanExecute and another one for the Execute… as simple as this…

   1: public class SimpleCommand : ICommand
   2: {
   3:     public Predicate<object> CanExecuteDelegate { get; set; }
   4:     public Action<object> ExecuteDelegate { get; set; }
   5:  
   6:     #region ICommand Members
   7:  
   8:     public bool CanExecute(object parameter)
   9:     {
  10:         if (CanExecuteDelegate != null)
  11:             return CanExecuteDelegate(parameter);
  12:         return true;// if there is no can execute default to true
  13:     }
  14:  
  15:     public event EventHandler CanExecuteChanged
  16:     {
  17:         add { CommandManager.RequerySuggested += value; }
  18:         remove { CommandManager.RequerySuggested -= value; }
  19:     }
  20:  
  21:     public void Execute(object parameter)
  22:     {
  23:         if (ExecuteDelegate != null)
  24:             ExecuteDelegate(parameter);
  25:     }
  26:  
  27:     #endregion
  28: }

and to create a command now is as simple as this…

   1: searchByNameCommand = new SimpleCommand
   2: {
   3:     CanExecuteDelegate = x => !String.IsNullOrEmpty(SearchText),
   4:     ExecuteDelegate = x => myDataView.Filter = stateObj => ((Person)stateObj).Name.Contains(SearchText)
   5: };

and yes you could say that it is a 1 line of code :P (well a long one maybe :) )… yet of course, you can have as much logic in there as you want!

 

If you want to see a sample project I created a demo app that you can download here.

kick it on DotNetKicks.com

Fix scrollbars for a dynamic layout in a Listview/ListBox

Some colleagues at work had a problem today with a ListView that had a dynamic layout. Basically we had a ListView that contained an Expander as one of the CellTemplates, the Expander had another ListBox inside that contained several items. The problem with this was that the ScrollBar for the ListView (which contained all the Expanders) was freaking out and behaving like it was drunk. Here is the XAML for this.

   1: <ListView ItemsSource="{Binding}" >
   2:     <ListView.View>
   3:         <GridView>
   4:             <GridViewColumn Header="Test">
   5:                 <GridViewColumn.CellTemplate>
   6:                     <DataTemplate>
   7:                         <Expander Header="Test">
   8:                             <ListBox ItemsSource="{Binding}">
   9:                                 <ListBox.ItemTemplate>
  10:                                     <DataTemplate>
  11:                                         <TextBlock Text="{Binding}"/>
  12:                                     </DataTemplate>
  13:                                 </ListBox.ItemTemplate>
  14:                             </ListBox>
  15:                         </Expander>
  16:                     </DataTemplate>
  17:                 </GridViewColumn.CellTemplate>
  18:             </GridViewColumn>
  19:         </GridView>
  20:     </ListView.View>
  21: </ListView>
  22:
  23: public Window1()
  24: {
  25:     DataContext = new[]
  26:         {
  27:             new [] { 50, 30, 20, 10, 40, 50, 70, 84, 20, 30, 50 },
  28:             new [] { 50, 30, 20, 10, 40, 50, 70, 84, 20, 30, 50 },
  29:             new [] { 50, 30, 20, 10, 40, 50, 70, 84, 20, 30, 50 },
  30:         };
  31:     InitializeComponent();
  32: }

In order to fix this there is a magic trick :)

All you have to do set an attached  property on the ListView to instruct it’s ScrollViewer that the Content cannot Scroll. so basically the XAML now would look like this

   1: <ListView ItemsSource="{Binding}" ScrollViewer.CanContentScroll="False">
   2:     <ListView.View>
   3:         <GridView>
   4:             <GridViewColumn Header="Test">
   5:                 <GridViewColumn.CellTemplate>
   6:                     <DataTemplate>
   7:                         <Expander Header="Test">
   8:                             <ListBox ItemsSource="{Binding}">
   9:                                 <ListBox.ItemTemplate>
  10:                                     <DataTemplate>
  11:                                         <TextBlock Text="{Binding}"/>
  12:                                     </DataTemplate>
  13:                                 </ListBox.ItemTemplate>
  14:                             </ListBox>
  15:                         </Expander>
  16:                     </DataTemplate>
  17:                 </GridViewColumn.CellTemplate>
  18:             </GridViewColumn>
  19:         </GridView>
  20:     </ListView.View>
  21: </ListView>

As you can see all I changed here is adding the attached property ScrollViewer.CanContentScroll=”False” on the ListView, and viola the scrolling now works correctly :)

Edit: After having a chat with a fellow WPF Disciple, Andrew Smith, he pointed out that this solution will drop Virtualization support. So if you have a lot of data this is probably not the best solution for you.