Saturday, October 1, 2011

MVVM using Silverlight 4.0

MVVM (Model, View and View Model) pattern is very useful for developing RIA applications and business applications where we have many views and different layers for logic and data management. Using MVVM we are somehow able to handle SOLID (Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion) which is basic principle of OOP (Object Oriented Programming) which is beauty of this pattern. MVVM is very much used in WCF and Silver-light Applications because of binding and test driven development.

 MVVM is new shape of MVC (Model View Controller) and MVP (Model View Presentation) which are very popular for various reasons (I will not go into it for now). In MVVM there is model is a layer which handles all the data base and repository duties, View is presentation layer or view of user where user interact with the applicatoin, View Model is glue or middle man layer between the View and Model.


 I will try to explain to you MVVM pattern by a small example of Employee.

 First open a Visual Studio 2010 new project and open select Silverlight Business Application from list.


Visual Studio will create a Navigation template for silverlight application by default.
There by default Views and Models folder there. In Models folder create you model Employees class.

public class Employee : INotifyPropertyChanged
{

            public event PropertyChangedEventHandler PropertyChanged;

            protected void OnPropertyChanged(string property)
            {
                if(PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(property));
                }

            }

        private string _firstName;
        public string firstName
        {
             get { return _firstName; }
             set
                {
                    if (value != null)
                    {
                        _firstName = value;
                        OnPropertyChanged("firstName");
                    }
                    else
                    {
                        Validator.ValidateProperty(value, new ValidationContext(this, null, null));
                    }
                }
        }

        private string _lastName;
        public string lastName
        {
            
            get { return _lastName; }
            set 
                { 
                    if(value != null)
                        _lastName = value;
                        OnPropertyChanged("lastName");
                }

        }


Our employee class is implementing a interface INotifyPropertyChanged which also providing the implemenation for its method.

I have used only two properties and a method OnPropertyChanged which will call upon the property changing by taking property name as arguments.

Create a folder ViewModels and create a ViewModel for our View and Model which is EmployeeView and Employee classes. EmployeeView is coming after this.

So here is our EmployeeViewModel


public class EmployeeViewModel : INotifyPropertyChanged
    {


        public event PropertyChangedEventHandler PropertyChanged;
        private ObservableCollection<Employee> _employees = new ObservableCollection<Employee>();


      
        public ObservableCollection<Employee> Employees
        {
            get { return _employees; }
            set
            {
                if (value != null)
                {
                    _employees = value;
                   
                }
            }
        }


        public void GetEmployeesFromRepository()
        {
            _employees.Add(new Employee {firstName = "Qasim", lastName = "Sarfraz"});
            _employees.Add(new Employee {firstName = "Per", lastName = "Hubnette"});
            _employees.Add(new Employee { firstName = "Lena", lastName = "Rohandin" });                          
            
            Employees = _employees;


        }


        public void AddEmpolyeesToRepository(string fname, string lname)
        {
            _employees.Add(new Employee { firstName = fname, lastName = lname});
            
        }



Again it is very simple ViewModel class it has one property which is observable collection and two methods one for getting employee from repository and second method is just add employee to repository  (in our case repository is our employee Model class).

Now lets move towards our View. Add a Silverlight page name as EmployeeView in Views folder and add this code



<UserControl x:Class="TrackAndTrace.Client.MainPage"
    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="White">
        <ListBox x:Name="lbPeople" Margin="100,0,100,61" HorizontalAlignment="Center"
                             ItemsSource="{Binding Employees}" ScrollViewer.HorizontalScrollBarVisibility="Hidden" Width="200">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="100" />
                            <ColumnDefinition Width="100" />
                            
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" Margin="10" Text="{Binding firstName}" />
                        <TextBlock Grid.Column="1" Margin="10" Text="{Binding lastName}" />
                       
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="277,250,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="12,250,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
        <TextBox Height="23" HorizontalAlignment="Right" Margin="0,250,142,0" Name="textBox2" VerticalAlignment="Top" Width="120" />
    </Grid>
</UserControl>

Here is few lines of code for codebehind file of EmployeeView

 EmployeeViewModel evm = new EmployeeViewModel();

        public EmployeeView()
        {
            InitializeComponent();
            
            evm.GetEmployeesFromRepository();

            LayoutRoot.DataContext = evm;

        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {

            evm.AddEmpolyeesToRepository(textBox1.Text, textBox2.Text);
        }

Again its very simple in our EmployeeView page we have a ListBox with item template which has two columns. Each column has a TextBox where as its Text property is bind to our Model properties. It has two Texboxes and a button to add our new employee. This line of code will start the magic of MVVM

 LayoutRoot.DataContext = evm;


Lets run it you will see the magic of MVVM.


If you any question or feedback please you can comment. Don't forget to like the post.

Thank!

No comments:

Post a Comment