Skip to main content

Silverlight MVVM

What is MVVM pattern as per wikipedia "The Model View ViewModel (MVVM) is an architectural pattern used in software engineering that originated from Microsoft as a specialization of the Presentation Model design pattern introduced by Martin Fowler.[1] Largely based on the model–view–controller pattern (MVC), MVVM is a specific implementation targeted at UI development platforms which support the event-driven programming in Windows Presentation Foundation (WPF) and Silverlight on the .NET platforms using XAML and .NET languages. Technically different, but similar, Presentation Model design patterns are available in HTML5[2][3] through KnockoutJS, and for Java the ZK framework (Model-View-Binder)."







ViewModelBase.cs




using System;
using System.ComponentModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace MVVMDEMO.ViewModel
{
    /// <summary>
    /// 
    /// </summary>
    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            var propertyChanged = PropertyChanged;

            if (propertyChanged != null)
            {
                propertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }



    }
}


Person.cs




using MVVMDEMO.ViewModel;
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace MVVMDEMO.Model
{
    /// <summary>
    /// 
    /// </summary>
    public class Person:ViewModelBase
    {
        private int _personID;
        public string _firstName;
        public string _lastName;
        public int _age;
        public string LastName
        {
            get
            {
                return _lastName;
            }
            set
            {
                _lastName = value;
                OnPropertyChanged("LastName");
            }
        }
        public string FirstName
        {
            get
            {
                return _firstName;
            }
            set
            {
                _firstName = value;
                OnPropertyChanged("FirstName");
            }
        }
        public int PersonID
        {
            get { return _personID; }
            set
            {
                _personID = value;
                OnPropertyChanged("PersonID");
            }
        }

        public int Age
        {
            get
            {
                return _age;
            }
            set
            {
                _age = value;
                OnPropertyChanged("Age");
            }
        }
    
        
       
    }
}



MainPageViewModel.cs





using MVVMDEMO.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace MVVMDEMO.ViewModel
{
    public class MainPageViewModel : ViewModelBase
    {
        private ObservableCollection<Person> _person;
        private Person selectedPerson;
        private ICommand _SaveCommand;
        public MainPageViewModel()
        {
            _person = new PersonRepository().Person;
            Commands();
        }

        public ObservableCollection<Person> PersonModel
        {
            get { 
                return _person;
            }
            set
            {
                _person = value;
                OnPropertyChanged("PersonModel");
            }
        }
       /// <summary>
       /// Get/Sets the value of Selected Person
       /// </summary>
        public Person SelectedPerson
        {
            get { return selectedPerson; }
            set
            {
                selectedPerson = value;
                OnPropertyChanged("SelectedPerson");
            }
        }
        /// <summary>
        /// Expose a filed of type ICommand
        /// </summary>
     
        public ICommand SaveCommand
        {
            get
            {
                return _SaveCommand;
            }
        }

        private void Commands()
        {
            _SaveCommand = new DelegateCommand<Person>(OnSaveCommand);
        }
        private void OnSaveCommand(Person s)
        {
            new PersonRepository().Update(s);

        }
    }
}


DelegateCommand.cs





using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace MVVMDEMO
{
    public class DelegateCommand<T> : ICommand
    {
        /// <summary> 
        /// Defines the method for the action to be executed. 
        /// </summary> 
        private readonly Action<T> executeAction;

        /// <summary> 
        /// Defines the function that determines whether the 
        /// action can be executed. 
        /// </summary> 
        private readonly Func<T, bool> canExecuteAction;

        ///<summary> 
        /// Defines an event to raise when the values that 
        /// affect "CanExecute" are changed. 
        public event EventHandler CanExecuteChanged;

        /// <summary> 
        /// Constucts an object that can always execute. 
        /// </summary> 
        /// <param name="currentExecuteAction"></param> 
        /// <remarks></remarks> 
        public DelegateCommand(Action<T> executeAction): this(executeAction, null){}
        
        /// <summary> 
        /// Constructs an object to execute. 
        /// </summary> 
        public DelegateCommand(Action<T> executeAction,Func<T, bool> canExecuteAction)
        {
            this.executeAction = executeAction;
            this.canExecuteAction = canExecuteAction;
        }

        /// <summary>   
        /// Defines the method that determines whether the command can 
        /// execute in its current state.   
        /// </summary>    
        public bool CanExecute(object parameter)
        {
            if (canExecuteAction != null)
            {
                return canExecuteAction((T)parameter);
            }
            return true;
        }

        /// <summary>   
        /// Defines the method to call when the command is invoked.   
        /// </summary>    
        public void Execute(object parameter)
        {
            if (CanExecute(parameter))
            {
                executeAction((T)parameter);
            }
        }
    }
}


PersonRepository.cs






using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Linq;
using System.Linq.Expressions;
namespace MVVMDEMO.Model
{
    /// <summary>
    /// 
    /// </summary>
    public class PersonRepository
    {
        public ObservableCollection<Person> Person { get; set; }

        public PersonRepository()
        {
            GeneratePersonList();
        }
        public void Update(Person singlePerson)
        {
            var person = Person.Where(x => x.PersonID == singlePerson.PersonID).FirstOrDefault();
            person.FirstName = singlePerson.FirstName;
            person.LastName = singlePerson.LastName;
            person.Age = singlePerson.Age;
        }
        private void GeneratePersonList()
        {
            Person = new ObservableCollection<Person>() 
            {
                new Person() { PersonID = 1, FirstName = "Erandika",    LastName = "Sandaruwan", Age=25 },
                new Person() { PersonID = 2, FirstName = "Niluka",      LastName = "Dilani",     Age = 30},
                new Person() { PersonID = 3, FirstName = "Chathura",    LastName = "Achini",     Age = 27},
                new Person() { PersonID = 4, FirstName = "Florina",     LastName = "Breban",     Age = 25},
            };
        }
    }
}

MainPage.xaml



<UserControl x:Class="MVVMDEMO.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"
             xmlns:local="clr-namespace:MVVMDEMO.ViewModel"
             mc:Ignorable="d"
             d:DesignHeight="400"
             d:DesignWidth="600">
    <UserControl.Resources>
        <local:MainPageViewModel x:Key="ViewModel" />
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot"
          Background="White"
          DataContext="{StaticResource ViewModel}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="250" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <ListBox Grid.Column="0"
                 Margin="5"
                 Height="200"
                 VerticalAlignment="Top"
                 ItemsSource="{Binding PersonModel}"
                 DisplayMemberPath="FirstName"
                 SelectedItem="{Binding SelectedPerson, Mode=TwoWay}" />
        <Grid x:Name="PersonDetails"
              Grid.Column="1"
              DataContext="{Binding SelectedPerson}"
              Margin="10">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="150" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
                <RowDefinition Height="20" />
                <RowDefinition Height="20" />
                <RowDefinition Height="20" />
                <RowDefinition Height="20" />
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0"
                       Grid.ColumnSpan="2"
                       Text="Person Details"
                       FontSize="15" />

            <TextBlock Grid.Row="1"
                       Grid.Column="0"
                       Text="FirstName" />
            <TextBox Grid.Row="1"
                     Grid.Column="1"
                     Text="{Binding FirstName, Mode=TwoWay}" />

            <TextBlock Grid.Row="2"
                       Grid.Column="0"
                       Text="LastName" />
            <TextBox Grid.Row="2"
                     Grid.Column="1"
                     Text="{Binding LastName, Mode=TwoWay}" />

            <TextBlock Grid.Row="3"
                       Grid.Column="0"
                       Text="Age" />
            <TextBox Grid.Row="3"
                     Grid.Column="1"
                     Text="{Binding Age, Mode=TwoWay}" />

            <Button Grid.Row="4"
                       Grid.ColumnSpan="2" Width="100"
                    Content="Save"
                    Command="{Binding SaveCommand,  Mode=OneWay, Source={StaticResource ViewModel}}"
                    CommandParameter="{Binding Mode=OneWay}" />

        </Grid>

    </Grid>
</UserControl>

Comments

Popular posts from this blog