DCSIMG
How to Develop MVVM Silverlight applications with Prism - Ariel's Remote Data Center

How to Develop MVVM Silverlight applications with Prism

Posted Oct 24 2010, 01:55 AM by Ariel Ben Horesh  

I’ve got some criticism from Alex Golesh in a comment on one of my latest Posts (Managing Silverlight resources contained in external assemblies), First I would like to thank him for taking his time and writing this comment, I would like to reply him with this post.

First let’s see Alex’s Comment:

I have to comment it, because the code lead to bad practice...

First, it heavily assumes you have all you assemblies in single XAP package - which is a bad practice for "heavy" Silverlight applications and especially real MVVM based applications.

Second, XamlReader will throw an exception if you resource (XAML) have a refernces to external resource dictionaries.

Last, but not least, this code will not work in SL3 and Silverlight for Windows Phone 7.

Regards,

Alex

Alex’s first point is what really made me write this following post, but I will get to it later. His second point is just plain wrong, I’ve created a small sample proving it, it is not very interesting sample as it self in my opinion but I just don’t want you, dear reader, to refrain from this solution on basis of Alex’s false assumption. You can download it here.

About Alex’s last point, It might be that it will not work in SL3, I’ve not tried to test it on that SL version,  Even how I wouldn’t recommend you developing RIA in SL3. About Windows Phone, I reckon that on the Phone platform a different approach is needed to be used, the code to manage resources is used when writing decoupled modules should be tuned to the platform specific needs. Anyway it is out of scope from this post, I will leave it for future post.

Now, let’s talk about Alex’s first point, it really boiled my blood Smile, an assumption so wrong, I’ve not heard for a long time, the whole purpose of that post was to allow you writing separate modules (which every module comes as his own XAP package) by keeping resources separate as well in order to refrain from tight coupling it in the first place. Now what really made me laugh is that each resource dictionary usually contains DataTemplates which pair a view and its ViewModel, an essential phase for maintaining MVVM Open-mouthed smile.

In Alex’s defense, he could have never known the full picture, how does that one piece of the puzzle fits in a larger picture.

That large picture is what I mean to present here. 

Let’s get started with Developing MVVM Silverlight App

First of all, I will be using Prism 2.2, as I’m writing this post, it is a the release version of Prism.

I will be following Prism’s guidance, as I truly believe in it and my experience with it from the day it was born has been very successful. I’ve started developing Prism with WPF and when I’ve made a switch in Silverlight I’ve tried to maintain the same methods of implementation. I will be covering some of Prism  main features in this post so a knowledge in Prism is very useful.

You better download the sample now, as I will be explaining it, and it might be easier for you to follow with that code in front of you. You can download it here.

The solution contains:

  1. 3rd Party folder: we will keep compiled assemblies such as Prism’s assemblies, other controls vendors assemblies.
  2. Client folder: we will keep projects related to our client, such as Modules and Common projects referenced by all modules.
  3. Silverlight Main Project: It contains the Shell view, we will inject views into it.
  4. ASP.Net Main Host: For this sample purpose it will be the default generated host you got from the Visual Studio Wizard.

Let’s investigate the Common project: This project is referenced by all modules, and must not reference any other project. I kept it as minimal as possible so it will contains only essential items for this sample to function.

Let’s see my version of ViewModelBase, it appears everybody got one Smile.

public class ViewModelBase<T> : ViewModelBase
{
    public new virtual T Model
    {
        get { return (T)base.Model; }
        set { base.Model = value; }
    }

    protected override void ModelChanged()
    {
        OnPropertyChanged(() => Model);
    }
}

I find it convenient that when I am binding a ViewModel to a View, I always got a Model property to use, making it reoccurring pattern to follow, and  it will not constrain you in any way, we will see it in use soon.

public class TemplateContentControl : ContentControl
{
    protected override void OnContentChanged(object oldContent, object newContent)
    {
        base.OnContentChanged(oldContent, newContent);
        if (newContent is UIElement) return;

        string key = newContent.GetType().Name;
        
        ContentTemplate = (DataTemplate)Application.Current.Resources[key];
    }
}

This is an interesting piece of code, it’s main purpose is to replicate WPF’s DataTemplate DataType ability. When we add a ViewModel to the SL’ visual tree, this control is going to grab the relevant DataTemplate.

public class RegionNames
  {
      public const string MainRegion = "MainRegion";
      public const string LowerRegion = "LowerRegion";
  }

Regions are a fundamental feature of Prism. which allow you to specify a place-holder inside a view, and let another view get placed in that place-holder without really knowing where is that place-holder location on the screen and in it’s project, thus decoupling a view from it container.

In this specific sample I’ve also located here the Model of the application, usually it deserve a separate project, but in order to keep things more simple I’ve placed it in here.

We have finished browsing through the Common project, now let’s move forward to talk about Modules.

Modules are pieces of application functionality that are suppose to behave autonomously. How do you define Modules in your app, it is actually a difficult question to answer. It really does depend on various architectural considerations.

In this sample app we will maintain 2 separate modules, communicating between modules is an important matter that I will have to leave for future post.s To keep this sample simple, the 2 modules do not interact with each other.

In Silverlight scenario each Module is in fact a Silverlight Application template (and not a Silverlight class library), after it’s creation you can delete all the files being generated. Make certain that in your ASP.net Host, it expects it’s XAP from the Silverlight Applications Tab.

image

Each module follow a certain skeleton structure:

  1. [Name]Module.cs : an entry point which we will be called when our modules are loaded.
  2. Views : a folder which will hold all relevant views of a Module.
  3. ViewModels: a folder which will hold all relevant ViewModel of a module. every View got a ViewModel (but not every ViewModel got a view).
  4. Resources: a folder to hold a specific resources needed by that (and only that) module such as images and Resource Dictionaries. Atleast one ResourceDictionary I recommend to maintain.

Let’s see the entry point of a module.

public class PatientsModule : IModule
{
    private readonly IUnityContainer _container;
    private readonly IRegionManager _regionManager;

    public PatientsModule(IUnityContainer container, IRegionManager regionManager)
    {
        _container = container;
        _regionManager = regionManager;
    }

    public void Initialize()
    {
        RegisterResources();
  _regionManager.AddToRegion(RegionNames.LowerRegion, _container.Resolve<PatientsViewModel>());
} private static void RegisterResources() { Assembly assembly = Assembly.GetExecutingAssembly(); string assemblyName = assembly.FullName; string[] nameParts = assemblyName.Split(','); var dictionary = new ResourceDictionary(); StreamResourceInfo resourceInfo =
        Application.GetResourceStream(new Uri(
        nameParts[0] + ";component/Resources/ModuleResources.xaml", UriKind.Relative));
        var resourceReader = new StreamReader(resourceInfo.Stream);
        string xaml = resourceReader.ReadToEnd();
        var resourceTheme = XamlReader.Load(xaml) as ResourceDictionary;
        Application.Current.Resources.MergedDictionaries.Add(resourceTheme);
    }
}

First you will notice it contains the piece of code that started the whole issue (Smile) but now in context. Note that it got a few basic stuff injected to it such as Unity (IoC Container) and RegionManager.

The initialize is in fact the method that will get called once a module is loaded. In this case create a new instance of a specific ViewModel (using Unity’s Reslove) and using the RegionManager we inject it to the MainRegion place-holder. Complicated? perhaps but it will grow on you once you get use to it Smile.

Note that by passing to the RegionManager a non-visual object we are depending on DataTemplates to tell Silverlight how to render that kind of an object. This is where our Resource Dictionaries and TemplateContentControl come into place.

Let’s see an example of a ViewModel.

public class PatientsViewModel : ViewModelBase<IEnumerable<Patient>>
    {
        public PatientsViewModel()
        {
            Model = new List<Patient>
                        {
                            new Patient {FullName = "Margol Raz"},
                            new Patient {FullName = "Jim Brown"},
                            new Patient {FullName = "Lazy Fox"}
                        };
        }
    }

Note that by deriving from ViewModeBase we got a Model property of type IEnumerable<Patient> we can make use. For the sake of a simplicity I’m just filling it up with some data. Usually you get it from a service or other means of persistency.

Now let’s check out a View

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="100"/>
        </Grid.RowDefinitions>
        <ListBox ItemsSource="{Binding Model}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock FontSize="16" Text="{Binding FullName}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>            
    </Grid>    

We can clearly see we databind to the Model property of the ViewModel.

We have gone over some very important aspects but how the ViewModel get hold of it’s View? It all depend on the ResourceDictionary.

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml 
    xmlns:Views="clr-namespace:Patients.Client.Modules.Patients.Views;assembly=Patients.Client.Modules.Patients">
    
    <DataTemplate x:Key="PatientsViewModel">
        <Views:PatientsView/>
    </DataTemplate>
</ResourceDictionary>

A very important points to remember here:

  • It is important to keep the key of the resource the same type name of the ViewModel otherwise the TempalteContentControl will not be able to locate it.
  • You must specify the full namespace of the views even though it is in the same project (working around a possible bug).
  • The most important thing to remember his the that Silverlight (and WPF in that prespective) will push the ViewModel to the DataContext of the View, this is how DataTemplates are functioning, and this is why DataBinding are easy as a breeze in MVVM and in my purposed way of implementing it.

Our 2nd Module is very similar and will not cover it in here. It is just to prove Alex we still keep are apps in good code practice Smile.

Our last project we will go over together is the Shell project. It contains a Bootstrapper class that is doing the Prism heavy lifting in the startup of the application, reading the configuration file, loading up the modules, setting up Unity Container and RegionManager, etc.

<Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="50*"/>
            <RowDefinition Height="50*"/>
        </Grid.RowDefinitions>
        <com:TemplateContentControl Regions:RegionManager.RegionName="MainRegion" />
        <com:TemplateContentControl Grid.Row="1" Regions:RegionManager.RegionName="LowerRegion" />
    </Grid>

This is our Shell, all it contains is the placeholders for the modules to inject their ViewModels. note the usage of TemplateContentControl.

Conclusion

We have covered a lot of stuff today.

We have gone through creating a small sample in MVVM, Prism and I hope now it will be up to the high standards of the Silverlight Community.

Ariel


Comments

Ariel Ben Horesh said:

@Micky

I've checked out Caliburn for WPF  a long time ago. But as for your recommendation I will check out the Micro assembly.

Thanks a lot for your comment!

Ariel

# October 24, 2010 10:44 AM

Twitter Trackbacks for How to Develop MVVM Silverlight applications with Prism - Ariel's Remote Data Center [microsoft.co.il] on Topsy.com said:

Pingback from  Twitter Trackbacks for                 How to Develop MVVM Silverlight applications with Prism - Ariel's Remote Data Center         [microsoft.co.il]        on Topsy.com

# October 24, 2010 1:14 PM

Alex Golesh's Blog About Silverlight Development said:

I thought a lot before decided to write this post… First - I’d like to thanks Ariel Ben Horesh for “inspiring

# October 24, 2010 8:42 PM

Community Blogs said:

I thought a lot before decided to write this post… First - I’d like to thanks Ariel Ben Horesh for “inspiring

# October 24, 2010 9:28 PM

eladkatz said:

mvvm good. prism bad. I'm with Micky.

you're working SOOOO hard, for something u don't need. prism doesn't do anything good for you. you're better off using cliburn or mvvm light (my preference.)

# October 25, 2010 4:12 AM

Dew Drop – October 25, 2010 | Alvin Ashcraft's Morning Dew said:

Pingback from  Dew Drop &ndash; October 25, 2010 | Alvin Ashcraft&#039;s Morning Dew

# October 25, 2010 1:43 PM

Microsoft Weblogs said:

This is Windows Client Developer roundup #48. The Windows Client Developer Roundup aggregates information

# November 2, 2010 12:21 AM

concertus said:

Why should I live?

# April 2, 2011 9:29 AM

Rafael Soteldo said:

This is good stuff. It comprehends Modularity, MVVM, Prism 4.

All I was looking for in one example.

Although the project doesn¡t seem to run properly, it's the programming what interests me.

Thank you!

# June 14, 2012 5:06 PM

developer said:

Your XmlReaderTest doesn't prove that having references to external disctionaires doesn't throw an exception.

It's basically the same xaml as the PrimSLTest but without the MedicalStaffModules.

How can you prove that?

# June 14, 2012 9:56 PM

Rhiniidiome said:

xpwdygwy <a href=sacvuittonsonlinesoldes.com#8972>louis">sacvuittonsonlinesoldes.com vuitton pas cherb</a> aldgcbil <a href="sacvuittonsonlinesoldes.com#1152">louis">sacvuittonsonlinesoldes.com vuitton soldesi</a> ecynjsro sacvuittonsonlinesoldes.com

# September 13, 2012 10:34 AM

bspfjoech@gmail.com said:

Hi, great article it's exactly the point

# December 7, 2012 11:14 AM

annerfoto said:

[url=http://www.msaz.info]ugg outlet[/url] pzg xcq

bqu ssc

[url=http://www.srlz.info]ugg boots sale[/url]  cvnqay

jwu vgj

[url=http://www.nm53.info]coach outlet[/url] baijgr

ufa sbh

# December 14, 2012 6:35 PM

wubdjrlyq@gmail.com said:

Very informative post. Thanks for taking the time to share your view with us

# December 16, 2012 5:02 PM

yerwoz@gmail.com said:

Watch the trailer for Kathryn Bigelow's follow-up to The Hurt Locker - a thriller based on the manhunt for Osama bin Laden

# December 18, 2012 10:26 AM

Atkins said:

Do you want to gain, or are you just out to have fun? Even so,

studying PPC can be really a overwhelming task,

in particular for newcomers.

# March 3, 2013 10:49 PM

Mcewen said:

Keep on working, great job!

# March 22, 2013 12:32 PM

Fulcher said:

I ought to and I sent it a make an effort with my teenage kids.

What does it mean if ever there are other books on your

subject? Regarding designs and almost all such designs have proven to be there to choose from.

Unquestionably the partner is hands-on in seeking

out of the house mentors and the relationship productive.

brandbazar.ru/.../16482

# March 28, 2013 11:03 AM

Haas said:

Get far good gasoline mileage along with your living vehicle.

Making a prenatal weight loss is fantastic because your state from health.

So we wil offer you some strategies to teach you in order

to choose. Experiencing knowledge is vital to using

anything sportfishing has to. http://themagic-social.

com/index.php?do=/blog/69320/nike-air-max-discount/

# April 20, 2013 10:17 AM

Roush said:

でもそこに茶色の色から選択するいくつかの色合いで

# April 20, 2013 10:50 AM

Tracey said:

&#12469;&#12531;&#12464;&#12521;&#12473;&#12398;&#21508;&#12475;&#12483;&#12488;

&#12399;&#12289;&#12381;&#12398;&#20778;&#12428;&#12383;&#12487;&#12470;

&#12452;&#12531;&#12289;&#21697;&#36074;&#12398;&#32032;

&#26448;&#12392;&#12289;&#12381;&#12428;&#12364;&#20445;&#25345;

&#12375;&#12390;&#12356;&#12427;&#12456;&#12522;&#12540;&#12488;&#12398;&#21517;&#12395;

&#36020;&#37325;&#12394;&#12418;&#12398;&#12391;&#12377;&#12398;&#12391;&#12289;&#12471;&#12515;&#12493;&#12523;&#12398;&#12383;&#12417;&#12395;&#35504;&#12398;&#36023;&#12356;&#29289;&#12399;&#12289;

&#12381;&#12398;&#12467;&#12473;&#12488;&#12434;&#25903;&#25173;&#12358;

&#12383;&#12417;&#12395;&#28310;&#20633;&#12377;&#12427;&#24517;&#35201;&#12364;&#12354;

&#12426;&#12414;&#12377;

# April 20, 2013 11:00 AM

Guffey said:

良質の香水はあなたがどんなにシンプルなお洋服多分万ドルの匂いを嗅ぐことができます

# April 20, 2013 11:08 AM

Thibodeau said:

3Dのハンドバッグは黒茶色赤やピンクのような色と豪華さと貴重なトカゲワニやPythonのようなテクスチャを含む様々なバージョンで設計されています

# April 20, 2013 5:42 PM

Schuler said:

究極のバーバリーのスタイルが求められ人気があるものであり古典的に洗練されたデザインです。

# April 20, 2013 9:01 PM

Luna said:

あなたが最も本物のデザイナーハンドバッグはそれらの署名のロゴを持っていることがわかります

# April 20, 2013 11:26 PM

Irwin said:

プリティURLがまた混乱のビットであることができる 'この周りの2つの方法があります

# April 21, 2013 9:04 AM

Quinlan said:

軍風のトップス超セクシーなバーバリーのブーツとペアレザーレギンスはこの春と夏の古典的な外観になります

# April 21, 2013 2:27 PM

Stitt said:

Perhaps those that have style contacting but don't feature like the common cellphone that you really keep for an ears. I just hope people who can read this article would be able to absorb the message I wanted you to know.

# April 21, 2013 9:24 PM

Clapp said:

時折かなりの数のクラスの製品には限定版である

# April 21, 2013 10:19 PM

Sweat said:

&#12399;&#12289;&#38750;&#20523;&#29702;&#30340;&#12394;&#12454;&#12455;&#12502;&#12398;&#26368;&#36969;&#21270;&#12364;&#22679;&#21152;

&#12375;&#12390;&#12356;&#12427;&#29702;&#30001;&#12391;&#12377;&#12290;

&#31169;&#12399;&#12289;&#12354;&#12394;&#12383;&#12364;&#12356;&#12378;&#12428;&#12363;

&#12364;&#12384;&#12414;&#12373;&#12428;&#12390;&#12480;&#12454;&#12531;&#12375;&#12390;&#20445;&#12388;&#12398;&#12434;

&#21161;&#12369;&#12427;&#12383;&#12417;&#12395;&#21608;

&#12426;&#12395;&#22238;&#36578;&#12377;&#12427;&#12371;&#12392;

&#12364;&#12391;&#12365;&#12427;&#12371;&#12392;&#12364;&#12391;&#12365;&#12427;&#12424;&#12358;&#12395;&#12394;&#12427;5&#12388;&#12398;&#20998;

&#37326;&#12395;&#12362;&#12369;&#12427;&#12481;

&#12483;&#12503;&#12383;&#12356;&#36984;&#12435;&#12384;&#12289;&#12414;&#12383;&#12399;&#20605;&#36896;&#12467;&#12540;&#12481;&#12461;&#12515;&#12522;&#12450;

&#12420;&#20605;&#12467;&#12540;&#12481;&#20104;&#31639;&#36092;

&#20837;&#12395;&#34987;&#23475;&#12290;&#20170;&#12289;&#12371;&#12428;&#12425;&#12399;&#21336;&#12394;&#12427;&#25552;&#26696;&#12391;&#12377;&#29702;&#35299;&#12375;&#12390;&#12356;&#12414;

&#12377;&#12290;&#20605;&#36896;&#12399;&#12289;&#12381;&#12428;&#12425;

&#12364;&#20986;&#12390;&#20316;&#12427;&#12418;&#12398;&#12391;&#12289;&#12399;&#12427;&#12363;&#12395;&#23554;&#38272;&#23478;&#12392;&#12424;&#12426;&#24039;&#12415;&#12395;&#12394;&#12387;&#12390;&#12365;

&#12390;&#12356;&#12414;&#12377;&#12364;&#12289;&#12356;&#12367;&#12388;&#12363;&#12398;&#29305;&#23450;&#12398;&#38936;&#22495;&#12395;&#24467;&#12358;&#12371;&#12392;

&#12395;&#12424;&#12387;&#12390;&#12354;&#12394;&#12383;

&#12398;&#33258;&#24049;&#12434;&#20445;&#35703;&#12377;&#12427;&#12371;&#12392;&#12364;&#12391;&#12365;&#12414;&#12377;

# April 22, 2013 8:07 AM

Hutcherson said:

Moreover, you may well make excellent overhead from selling them yourself.

Will it be deemed that coincidence? Allow us to see if you separate the two at

the cash register. Now we'll carry a look during the Kindle Fire specifications to visit how it holds up. azdekorasyon.com/.../50728

# May 9, 2013 3:43 PM

oqhkube@gmail.com said:

Thank you for the good writeup. It in reality was once a amusement account it. Look complicated to far introduced agreeable from you! By the way, how could we keep in touch?

# May 14, 2013 5:56 PM

Provost said:

隠れてあなた水分しない意味する必要がありますが着ていると思うと不浸透性ので服ユーザーの服装することができます1つこと魅力のないルイ・ヴィトンベンダーを持っていますかなり市場向き、彼らができるを強調した、ファッション計画と同様トップ度

# May 17, 2013 3:26 PM

Tabor said:

Expecially豪華な女性荷物することができます配信うち、様々 なスタイルの女性。。悲しいことに、シャネルのレプリカのメーカーしない遵守すべての人概念。また、その柔軟性は置くに存在でサイズ。することができますを調べるauthenticy によってこれらの理解何を見てのあなたのバッグに。

# May 21, 2013 4:38 AM

Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: