Sharker Khaleed Mahmud's Blog

ASP.NET, MVC, BLEND, Silverlight, AJAX and JQuery

  • Me

    Sharker Khaleed Mahmud
  • Visit my recent blog silverlightips.wordpress.com

Silverlight Prism Part 2 : Model View View Model (MVVM) Concept

Posted by Sharker Khaleed Mahmud | shamrat231 on November 25, 2009

Before we start with the part 2, I would like to introduce you to the concept of ModelView-View-Model (MVVM). We will be integrating MVVM in this part by giving simple example.

MVVM

MVVM is a great pattern to start with. MVVM allows the user to separate the View from the data and logic layer. So basically the designer can work on the xaml part on the blend while the developer can work on the data and logic on a separate view model class. In other words, separation of presentation layer and data access layer is being done very easily.

VIEWS

A view can be a simple xaml usercontrol. Usually, you put it in a Views folder. You can put resources, animation, navigation, powerful bindings and themes in the usercontrol. I would suggest that you put the resource in different places like in App.xaml but it is easier for the designer to work on the xaml control in blend if the resources are there. You will be leaving the data logic of binding in your view model class and not in your Views usercontrol (.cs) and thus loose coupling allows greater reusability and easier Dependency Injection(DI) and maintainability .

This is a continuation of Silverlight Prism Part 1 : Get Started of Silverlight Prism. So lets change some of the name and create some directories as shown below to introduce MVVM. For simplicity, we will create directory for each part of Model View ViewModel.

So first lets look at the model class where i will be creating properties for our stories. I will be using Scott Digg example here.

StoriesMdel.cs

    public class StoriesModel
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public int NumDiggs { get; set; }
        public Uri HrefLink { get; set; }
        public string ThumbNail { get; set; }
    }

So basically that is an example of model i.e stories. I will now use this model in our view model class by creating dummy collection and modifing the views to show some actual output. For this we will copy the code from Digg  example and put it in our view. I will also be using the same design (App.xaml) that Scott created. At the moment, I am reusing only six Scott styles in the (SearchModuleResultViewModel.xaml) view.

The styles that I have used here are 

  1. DiggPanel
  2. StoriesList
  3. NumDiggs
  4. NumDigsSubBlock
  5. ThumbNailPreview
  6. TitleBlock

SearchModuleResultView.xaml (View)

<UserControl x:Class=”SimplePrismApplication.Search.SearchModuleResultView”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml
    xmlns:d=”http://schemas.microsoft.com/expression/blend/2008
    xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006
    mc:Ignorable=”d”
    d:DesignHeight=”300″ d:DesignWidth=”400″>
    <Grid x:Name=”LayoutRoot” Background=”Beige” Height=”300″>
        <ListBox x:Name=”StoriesList” Style=”{StaticResource StoriesList}” ItemsSource=”{Binding Stories}”>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation=”Horizontal”>
                        <!– Yellow Digg Panel with NumDiggs–>
                        <StackPanel Style=”{StaticResource DiggPanel}” >
                            <TextBlock Text=”{Binding NumDiggs}” Style=”{StaticResource NumDigsBlock}” />
                            <TextBlock Text=”diggs” Style=”{StaticResource NumDigsSubBlock}” />
                        </StackPanel>
                        <!– Story Thumbnail Preview –>
                        <Image Source=”{Binding ThumbNail}” Style=”{StaticResource ThumbNailPreview}” />
                        <!– Story Title–>
                        <TextBlock Text=”{Binding Title}” Margin=”5″ Style=”{StaticResource TitleBlock}”/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</UserControl>

Put the styles in App.xaml file for now. Now, all left is to create some dummy variables and see the output. At code level, we will create constructor injection by injecting our view model in the constructor of the view like this.

SearchModuleResultView.xaml.cs

    public partial class SearchModuleResultView : UserControl
    {
        public SearchModuleResultView(SearchModuleResultViewModel viewModel)
        {
            InitializeComponent();
            this.DataContext = viewModel;
        }
    }

We have set the DataContext to the view model, thus taking care of binding. So lets create some dummy variables and see if this works or not.

SearchModuleResultViewModel.cs

    public class SearchModuleResultViewModel
    {
        public List<StoriesModel> Stories { get; set; }

        public SearchModuleResultViewModel()
        {
            Stories = Stories ?? new List<StoriesModel>();

            Stories.Add(new StoriesModel { Title=”example 1″, Description= “fdfd”, NumDiggs=2 });
        }
    }

Static content output.

Hmm, so far we have tested the MVVM concept and implemented digg sample using static content. Now we will test it using live web service.  Before we create webservice, we need to create an interface. So lets add a new folder call WebService and add a new interface class called ISimpleService.cs. In here we add a method search to do search with a callback mechanism.

ISimpleService.cs

using System.Collections.Generic;

namespace SimplePrismApplication.Search
{
    public interface ISimpleService
    {
        void DiggSearch(string value, Action<IEnumerable<StoriesModel>> SearchCallBack);
    }
}

Now we need to add reference of this interface to the view model class.

SearchModuleResultViewModel.cs

    public class SearchModuleResultViewModel
    {
        public List<StoriesModel> Stories { get; set; }
        public ISimpleService DiggService { get; set; }

        public SearchModuleResultViewModel(ISimpleService service)
        {
            Stories = Stories ?? new List<StoriesModel>();
            this.DiggService = service;
            this.DiggService.DiggSearch(“baseball”, OnSearchCompleted);
        }

        private void OnSearchCompleted(IEnumerable<StoriesModel> StoriesModel)
        {
            this.Stories.Clear();
            foreach(StoriesModel story in StoriesModel)
            {
                this.Stories.Add(story);
            }
        }
    }

We will add a webservice called Service.cs in WebService folder inheriting the interface ISimpleService.cs. Also add a reference of System.Xml.Linq to your Silverlight project. Reusing the code from Scott blog, it looks like this.

DiggService.cs

using System.Xml.Linq;
using System.Linq;

namespace SimplePrismApplication.Search
{
    public class DiggService : ISimpleService
    {
        public void DiggSearch(string value, Action<IEnumerable<StoriesModel>> SearchCallBack)
        {
            // url
            string url = String.Format(“http://services.digg.com/stories/topic/{0}?count=20&appkey=http%3A%2F%2Fscottgu.com“, value);

            // Initiate Async Network call to Digg
            WebClient service = new WebClient();
            service.DownloadStringCompleted += (sender, e) => SearchCallBack(DisplayStories(e));
            service.DownloadStringAsync(new Uri(url));
        }

        private IEnumerable<StoriesModel> DisplayStories(DownloadStringCompletedEventArgs e)
        {
            XDocument xmlStories = XDocument.Parse(e.Result);

            var stories = from story in xmlStories.Descendants(“story”)
                          where story.Element(“thumbnail”) != null &&
                                !story.Element(“thumbnail”).Attribute(“src”).Value.EndsWith(“.gif”)
                          select new StoriesModel
                          {
                              Id = (int)story.Attribute(“id”),
                              Title = ((string)story.Element(“title”)).Trim(),
                              Description = ((string)story.Element(“description”)).Trim(),
                              ThumbNail = (string)story.Element(“thumbnail”).Attribute(“src”).Value,
                              HrefLink = new Uri((string)story.Attribute(“link”)),
                              NumDiggs = (int)story.Attribute(“diggs”),
                          };

            return stories;
        }
    }
}

Now hitting F5 will not display the output as in this case we are using web service, not static content. So we need to register the webservice in the UnityContainer. We do that in our module section.

in the SearchModule constructor we set

        public SearchModule(IRegionManager regionManager, IUnityContainer container)
        {
            this.regionManager = regionManager;
            this.container = container;
        }

and register the service in the IUnityContainer like this

        public void Initialize()
        {
            this.container.RegisterType<ISimpleService, DiggService>(new ContainerControlledLifetimeManager());
            this.regionManager.RegisterViewWithRegion(“ResultRegion”, typeof(SearchModuleResultView));
        }

Hit F5 and see the output. Funny thing it will not show the deserved output. Why? The binding is being done before we receive the data from the webservice. Well that is the scenario at the moment. Now to avoid that i will use ObservableCollection instead of List like this

Output

Thanks
Sharker Khaleed Mahmud
Software Developer
(MCP,MCTS,MCPD[web])

References:

5 Minute Overview of MVVM in Silverlight : JohnPapa.net
Codeplex Sample
Scott DiggExample

Advertisements

7 Responses to “Silverlight Prism Part 2 : Model View View Model (MVVM) Concept”

  1. By separating the model from the view, you can change one without changing the other. Marley Webservice

  2. Suman said

    Good One dude..

  3. Suman said

    Why dont you extend this using Event Aggregators for communication between different modules. Seconldy it would be better if you can use WCF Services coz Silverlight Apps are using WCF for Data Operations. So far articles makes a great sense and easily understandable.

    • shamrat231 said

      I will write another article on Silverlight Flickr where i will use WCF service this month. I will try to implement event aggregators in another example of prism if i have time.

  4. […] https://sharkerkhaleedmahmud.wordpress.com/2009/11/25/silverlight-prism-part-2-model-view-view-model-… […]

  5. KAPIL MALHOTRA said

    Hi dude,

    Where are you using the DisplayStories method for binding the data to view.

  6. 7 osi layers…

    […]Silverlight Prism Part 2 : Model View View Model (MVVM) Concept « Sharker Khaleed Mahmud's Blog[…]…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: