XAML Playground
about XAML and other Amenities

My Model-View-ViewModel exercise

2009-11-13T01:32:04+01:00 by Andrea Boschin

Senza-titolo-1 Some weeks ago I've worked on an exercise originally started to try writing a complete application with full Model-View-ViewModel pattern. I've created the application with Visual Studio 2008, Prism to integrate missing features and Ria Services July CTP to get access to a SQL Server 2008 Database.

The application is a little time tracker, and I've decided to attach it to this post because it was very useful to me to understand problems and missing things about the MVVM pattern.

In the next days I will write some words about these problems I found, but for now I only want to undisclose the application to let something download it and give me some comments about it.

If you decide to try the application remember to attach the database mdf in the zip file, to set the connection strings in the web.config and the credentials for reporting services if you want to setup it and finally enter "tracker" as username and p@ssw0rd as password.

I'm currently learning this pattern and I do not want to consider my implementation complete, perfect and without any error. So please let me know what do you think and how can I improve it. Thanks in advance.

Download: Elite.TimeTracker.zip (~820 Kb)

Categories:   Prism | Demo
Actions:   E-mail | del.icio.us | Permalink | Comments (2) | Comment RSSRSS comment feed

A Prism (Unity) Service to create Views

2009-08-31T21:10:03+01:00 by Andrea Boschin

After a long summer pause I’m back with this new post. This time I want to investigate an aspect of the Model-View-ViewModel pattern programming with Silverlight. During the summer I've started working on an application where I used Prism to implement MVVM and I found useful to write some code to easily create instance of views during application inizialization and during its lifetime. I really do not know if this is the better solution but I found it easy and useful so I've decided to share it with you. Let me say in this post I assume you are already aware of the reasons and benefits coming from the usage of the popular Model-View-ViewModel pattern and how the pattern works. I also assume you have a minimal knowledge of the Prism toolkit and Unity.

The relationship between the View and the ViewModel

In this section I would like to depict how the View and ViewModel collaborate and what we have to do to create an instance of a View and of its own ViewModel at the sole purpose of preparing the field for explaining my solution.

In the MVVM pattern the View represent the user interface and the ViewModel represent the business logic required to drive the informations displayed on the View. This way, every time we have to create a View we also have to create a specific ViewModel exposing the expected informations to be displayed. The ViewModel is not aware of the View, so It does not know how its properties are consumed, but it simply publish some data through some properties and the View will attach these properties using DataBinding.

What I've said reveal almost two things. The first is that the View does not know how the ViewModel works internally, but it have to know the structure of its surface. In other words the ViewModel have to implement a given well-known "interface" to let the View working fine. This interface contains only properties the View is expected to attach. This implementation is not truly required by the pattern but we can think it is near to reality.

The other thing we have to know is that to let the view binding to the ViewModel, we have to put the ViewModel in the DataContext of the View. So, the creation of the View involve the creation of a specific ViewModel -possibly implementing a given interface - and the assignment of this instance to the DataContext property of the View. Translating this concept in code we have to write something like this:

   1: MyView view = new MyView() 
   2: { 
   3:     DataContext = new MyViewModel() 
   4: }; 


In my projects I do not like to write this code because it does not let me impose to the ViewModel an interface implementation. I can obviously implement the interface but there is nothing checking that this implementation has been done. To avoid this problem I've decided to create a service I use every time I need to create a View. The service is responsible to check that the ViewModel implements a specific interface. So the creation of a View become this:

   1: // assuming "vbs" is an instance of the service 
   2: MyView view = vbs.CreateView<MyView>(); 

What is a service?

Before entering the service implementation details, I would like to explain what is a Service. As I've already said in the previous paragraphs I'm using , a.k.a . Prism is a collection of useful tools to let the developer apply easily the most common architectural patterns. For the purpose of this article we will use , a dependency injection container recently ported to Silverlight from the Microsoft Pattern and Practice team. It is available inside the Prism collection.

Unity is an "" container. It let you create and register instances of classes - giving them a lifetime manager responsible of how and when the class is created and destroyed - and then locate these classes when you need to use them. Creating a class and registering it in the IOC container let you having something similar to a service, always available and discoverable, you may dedicate to specific responsibility.

The purpose of Unity is to promote layer decoupling to enable unit testing of the applications, but this is out of the scope of this article. If you would like to read something about this argument please refer to the Unity home page on codeplex: http://www.codeplex.com/unity.

Anatomy of the ViewBuilderService

Now that I have briefly explained how a service works it is time to explain the basis of my ViewBuilderService. The trick is that the View have to declare somewhere the interface it expects the ViewModel to implement. We may have an interface "IMyViewModel" and a view "MyView" that can consume a ViewModel implementing this interface. Using a simple custom attribute we can decorate the View codebehind with the interface:

   1: [ViewModel(typeof(IMyViewModel))]
   2: public partial class MyView : UserControl
   3: {
   4:     public MyView()
   5:     {
   6:     }
   7: }

Declaring a custom Attribute is simple and it enable the ViewBuilderService to discover the interface to search for in the IOC container. In the next box there is the declaration of the ViewModelAttribute where I use the AttributeUsage attribute to inform the compiler where it have to expect the attribute to be applied.

   1: [AttributeUsage(AttributeTargets.Class)]
   2: public class ViewModelAttribute : Attribute
   3: {
   4:     public Type ViewModelType { get; set; }
   5:  
   6:     public ViewModelAttribute(Type viewModelType)
   7:     {
   8:         this.ViewModelType = viewModelType;
   9:     }
  10: }

To connect a ViewModel to its own interface we need to create the ViewModel and register it into the IOC container. This way the ViewBuilderService can read the ViewModelAttribute on the View and ask the container to resolve the interface and give us the ViewModel instance to put in the DataContext. The best place to register the ViewModels is a Module we have declared in the Unity Bootstrapper. In the sample attached to this article I've omitted to use a Module for the purpose of not complicate the sample. So the ViewModels are registered in the Bootstrapper itself.

   1: /// <summary>
   2: /// Registers the types.
   3: /// </summary>
   4: private void RegisterTypes()
   5: {
   6:     this.Container.RegisterType<IMyViewModel, MyViewModel>();
   7: }

Now all is ready and we can create the service. We have to remember that the service has to be registered in the IOC contained to be discoverable using the ServiceLocator. So we start creating a class that implements an interface IViewBuilderService:

   1: public class ViewBuilderService : IViewBuilderService
   2: {
   3:     private static IUnityContainer TheContainer { get; set; }
   4:  
   5:     public ViewBuilderService (IUnityContainer theContainer)
   6:     {
   7:         this.TheContainer = theContainer;
   8:     }
   9: }

The IViewBuilderService interface have to expose only a CreateView<T>() method we will implement in the service. This method is responsible of finding the ViewModel in the container, creating the View we specified in the T parameter and finally connect view and viewmodel together.

   1: public T CreateView<T>()
   2:     where T : UserControl, new()
   3: {
   4:     ViewModel vm = this.GetViewModel(typeof(T));
   5:     return new T() { DataContext = vm };
   6: }
   7:  
   8: private ViewModel GetViewModel(Type viewType)
   9: {
  10:     ViewModelAttribute attribute = 
  11:         viewType
  12:             .GetCustomAttributes(typeof(ViewModelAttribute), true)
  13:             .OfType<ViewModelAttribute>()
  14:             .SingleOrDefault();
  15:  
  16:     if (attribute == null)
  17:         throw new InvalidOperationException("Missing ViewModelAttribute");
  18:  
  19:     ViewModel vm = this.TheContainer.Resolve(attribute.ViewModelType) as ViewModel;
  20:  
  21:     if (vm == null)
  22:         throw new InvalidOperationException("Cannot Resolve ViewModel");
  23:  
  24:     return vm;
  25: }

Using the ViewBuilderService

It is time to use the service inside our applications. First of all we have to register the service into the IOC container. We can register the service like we already have registered the ViewModel using the RegisterType method. While we can use the same instance of the service in all the application we can use a ContainerControlledLifetimeManager. This type of lifetime manager will transform the service in a singleton instance.

   1: /// <summary>
   2: /// Registers the types.
   3: /// </summary>
   4: private void RegisterTypes()
   5: {
   6:     this.Container.RegisterType<IViewBuilderService, ViewBuilder>(
   7:         new ContainerControlledLifetimeManager());
   8:  
   9:     this.Container.RegisterType<IMyViewModel, MyViewModel>();
  10: }

Then now using the ServiceLocator we can discover the service when we need to create a View. The ServiceLocator is a Singleton class, that is capable to search registered types by its interface and return an instance. You can use the ServiceLocator everywhere you need to find the IViewBuilderService.  Here is the code to create a View and assign to the Shell:

   1: Grid grid = this.Shell.FindName("LayoutRoot") as Grid;
   2:  
   3: if (grid != null)
   4: {
   5:     IViewBuilderService vbs =
   6:         ServiceLocator.Current.GetInstance<IViewBuilderService>();
   7:  
   8:     MyView view = vbs.CreateView<MyView>();
   9:  
  10:     grid.Children.Add(view);
  11: }

Obviously I could use the RegionManager to put the new View into the user interface but I wanted to keep the example simple.

All the code I've tryied to explain in this post is attached at the end of the article. I hope you will find it useful in your applications and I will expect comments from you to improve my design and know your opinion about it.

Download: SilverlightPlayground.ViewBuilderService.zip (~430 kb)

Categories:   Prism | TIPS
Actions:   E-mail | del.icio.us | Permalink | Comments (4) | Comment RSSRSS comment feed

Use CollectionViewSource effectively in MVVM applications

2009-07-18T23:13:15+01:00 by Andrea Boschin

In a my I've outlined the new CollectionViewSource introduced in silverlight with the latest release. This control is really useful while we need to sort and filter collection of objects in memory, but if we need to use a Model-View-ViewModel pattern to develop our application there is some problems using the control.

To implement the MVVM pattern we need to inject a ViewModel into the View using the DataContext property. This is usual in this kind of application because we need to bind the properties of the ViewModel to the controls in the View. So if we need to use a CollectionViewSource we can try to bind a collection from the ViewModel to the CVS and then bind the control to the CVS itself. Unfortunately this approach does not work because we cannot bind the CVS directly to the DataContext of the page. Trying to do this operation we will get a AG_E_BAD_PROPERTY_VALUE exception because the control does not inherits from FrameworkElement so it does not support DataBinding.

However, if it were possible, the CollectionViewSource would force us to put a lot of code in the codebehind to handle the Filter event and the sorting property. So, we have to follow another way to use the CollectionViewSource effectively with this kind of applications.

How to use the CollectionViewSource

The only way to use the CollectionViewSource with the MVVP pattern is to expose it as the type of the bindable property. This way we can manage the properties of the CVS and handle the Filter event from inside the ViewModel without putting anything in the codebehind of the View.

First of all we have to create two properties in the ViewModel. The first property will be the ObservableCollection<T> and we will populate it with the data to display. This property can be private because it will be used only to feed the ColectionViewSource of the second property. Here is how to initialize the properties:

   1: /// <summary>
   2: /// Gets or sets the names.
   3: /// </summary>
   4: /// <value>The names.</value>
   5: public CollectionViewSource Names { get; set; }
   6:  
   7: /// <summary>
   8: /// Gets or sets the names internal.
   9: /// </summary>
  10: /// <value>The names internal.</value>
  11: private ObservableCollection<string> NamesInternal { get; set; }
  12:  
  13: /// <summary>
  14: /// Initializes a new instance of the <see cref="MainPageViewModel"/> class.
  15: /// </summary>
  16: public MainPageViewModel()
  17: {
  18:     this.NamesInternal = new ObservableCollection<string>();
  19:     this.Names = new CollectionViewSource();
  20:     this.Names.Source = this.NamesInternal;
  21:  
  22:     // populate the ObservableCollection
  23:     foreach (string item in DataSource.GetNames())
  24:         this.NamesInternal.Add(item);
  25: }

Now, to bind the CollectionViewSource in the XAML we have to rely on his View property. If we put a reference to the CVS in the property ItemsSource in the XAML it simply will not work. Here is how to correctly bind:

   1: <ListBox ItemsSource="{Binding Names.View}" Margin="5,5,5,1" Grid.ColumnSpan="4" />

Once we have connected the CVS to the collection and the UI to the CVS we can handle the commands from the View and interact with the CVS to modify how to display the data. In the sample I have a togglebutton that is raising a ChangeSortDirectionCommand. I use the DelegateCommand<T> from Prism V2.0 and when someone send the command I change the SortDescriptor in the CollectionViewSource.

In the same View the TextChanged event is raised when the user type in the textbox. This command handled by the ViewModel let the CVS refresh itself. This way the Filter event will be evaluated again and the View will be updated with the filter applied.

I've attached to the post a new version of the sample I've proposed with the first article. Now the sample use the MVVM pattern with the CollectionViewSource.

Download: Elite.Silverlight3.CollectionViewMVVM.zip (~520 KB)

Categories:   Prism | Databinding | Prism
Actions:   E-mail | del.icio.us | Permalink | Comments (1) | Comment RSSRSS comment feed

A code snippet to quickly write Prism commands

2009-07-09T22:16:53+01:00 by Andrea Boschin

Crawling the Internet there are many samples about how to write commands for the Composite Application Guidance, aka Prism v2.0. One of my favorites is the .

I figure out the first time you see how many code you need, to write a working command you are really astonished. This also happened to me. But if you analyze the code you will see that the skeleton of a command is always the same, and you need to change only some names and types to have it working on different events.

This is the perfect situation where a code snippet works effectively so I decided to write my own and publish on this site. I've isolated some zones you have to replace and I've created some markers that will take advantage of the Visual Studio expansion snippets.

  1. command: the name of the command you are writing (e.g. MouseOver)
  2. control: the control type your command apply to (e.g. Button)
  3. event: the event of the control your command will wrap


Here is the snippet:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
   3:     <CodeSnippet Format="1.0.0">
   4:         <Header>
   5:             <Title>prismcommand</Title>
   6:             <Shortcut>prismcommand</Shortcut>
   7:             <Description>Code snippet for an automatically implemented commands</Description>
   8:             <Author>Elite Agency</Author>
   9:             <SnippetTypes>
  10:                 <SnippetType>Expansion</SnippetType>
  11:             </SnippetTypes>
  12:         </Header>
  13:         <Snippet>
  14:             <Declarations>
  15:                 <Literal>
  16:                     <ID>command</ID>
  17:                     <ToolTip>Command Name</ToolTip>
  18:                     <Default>CommandName</Default>
  19:                 </Literal>
  20:                 <Literal>
  21:                     <ID>control</ID>
  22:                     <ToolTip>Control type</ToolTip>
  23:                     <Default>Control</Default>
  24:                 </Literal>
  25:         <Literal>
  26:           <ID>event</ID>
  27:           <ToolTip>Control Event</ToolTip>
  28:           <Default>Event</Default>
  29:         </Literal>
  30:       </Declarations>
  31:             <Code Language="csharp">
  32:         <![CDATA[public class $command$CommandBehavior : CommandBehaviorBase<$control$>
  33:     {
  34:         public $command$CommandBehavior($control$ targetObject)
  35:             : base(targetObject)
  36:         {
  37:             targetObject.$event$ += (s, e) => base.ExecuteCommand();
  38:         }
  39:     }
  40:  
  41:     public static class $command$
  42:     {
  43:         public static readonly DependencyProperty $command$BehaviorProperty =
  44:             DependencyProperty.RegisterAttached(    
  45:                 "$command$BehaviorProperty", typeof($command$CommandBehavior), 
  46:                 typeof($command$CommandBehavior), null);
  47:  
  48:         #region CommandProperty
  49:  
  50:         public static readonly DependencyProperty CommandProperty =
  51:             DependencyProperty.RegisterAttached(
  52:                 "Command", typeof(ICommand), typeof($command$),
  53:                 new PropertyMetadata(CommandProperty_Changed));
  54:  
  55:         public static ICommand GetCommand(DependencyObject obj)
  56:         {
  57:             return (ICommand)obj.GetValue(CommandProperty);
  58:         }
  59:  
  60:         public static void SetCommand(DependencyObject obj, ICommand value)
  61:         {
  62:             obj.SetValue(CommandProperty, value);
  63:         }
  64:  
  65:         private static void CommandProperty_Changed(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
  66:         {
  67:             $control$ targetObject = dependencyObject as $control$;
  68:  
  69:             if (targetObject != null)
  70:                 GetOrCreateBehavior(targetObject).Command = e.NewValue as ICommand;
  71:         }
  72:  
  73:         #endregion
  74:  
  75:         #region CommandParameterProperty
  76:  
  77:         public static readonly DependencyProperty CommandParameterProperty =
  78:             DependencyProperty.RegisterAttached(
  79:                 "CommandParameter", typeof(object), 
  80:                 typeof($command$), new PropertyMetadata(CommandParameterProperty_Changed));
  81:  
  82:         public static ICommand GetCommandParameter(DependencyObject obj)
  83:         {
  84:             return (ICommand)obj.GetValue(CommandParameterProperty);
  85:         }
  86:  
  87:         public static void SetCommandParameter(DependencyObject obj, ICommand value)
  88:         {
  89:             obj.SetValue(CommandParameterProperty, value);
  90:         }
  91:  
  92:         private static void CommandParameterProperty_Changed(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
  93:         {
  94:             $control$ targetObject = dependencyObject as $control$;
  95:  
  96:             if (targetObject != null)
  97:                 GetOrCreateBehavior(targetObject).CommandParameter = e.NewValue;
  98:         }
  99:  
 100:         #endregion
 101:         
 102:         private static $command$CommandBehavior GetOrCreateBehavior($control$ targetObject)
 103:         {
 104:             $command$CommandBehavior behavior = targetObject.GetValue($command$BehaviorProperty) as $command$CommandBehavior;
 105:  
 106:             if (behavior == null)
 107:             {
 108:                 behavior = new $command$CommandBehavior(targetObject);
 109:                 targetObject.SetValue($command$BehaviorProperty, behavior);
 110:             }
 111:  
 112:             return behavior;
 113:         }
 114:     }]]>
 115:             </Code>
 116:         </Snippet>
 117:     </CodeSnippet>
 118: </CodeSnippets>

To have this snipped installed you simply need to create a file named prismcommand.snipped and copy the code inside it (or simply download the attached file). This file has to be loaded in the My Code Snippets directory using the Code Snippet Manager in Visual Studio 2008.

Finally after creating a file in your project type "prismcommand" in the text editor and hit TAB. Two classes will be exploded and you will be asked to provide the expansion tags I listed above. Obviously you have to include the assemblies from Prism and reference the Microsoft.Practices.Composite.Presentation.Commands namespace to have it compile.

Download:

Categories:   Prism
Actions:   E-mail | del.icio.us | Permalink | Comments (2) | Comment RSSRSS comment feed