Click here to Skip to main content
15,867,308 members
Articles / Desktop Programming / WPF

Simplest MVVM Ever

Rate me:
Please Sign up or sign in to vote.
4.66/5 (31 votes)
14 Nov 2013CPOL5 min read 56.6K   1.5K   35   17
About major building blocks in layman terms, in order to make it easier to understand for beginners.

Background

Continuation to my previous article on WHY and WHEN of MVVM, this time, I am going to tell something on how we can create a simple MVVM application with minimal complexities. I am writing this article for those, who just want to see quickly how MVVM works. It doesn't do anything fancy and uses some basic databindings and commanding stuff. This article will be helpful for all those who are looking for a quick example of how to hook the View to the ViewModel and how commands play a role.

Today if you will surf the internet, you will came across 1000s of articles discussing what is MVVM and what are the major building blocks of it. So, I am going to repeat the same crazy thing again. But definitely, I'll brief you about major building blocks in layman terms, in order to make it easier to understand for beginners. Excited, eh???

Layman Introduction of Building Blocks

So, let's quickly start with three main layers of MVVM.

  • Model - Model contains the classes which are similar to real world entities like Product, Customer, Student, Invoice, etc. It encapsulates business logic and data. Please note, Model classes do not directly reference view or in other way, Model classes have no dependency on view as how they are implemented. Technically speaking, Model classes are used in conjunction with a service or a repository that encapsulate data access.
  • ViewModel - Main purpose of ViewModel classes is to expose data to the view. It includes presentation logic and can be tested independently of Model. Similar to Model, ViewModel never references View but it exposes properties and commands to bind the View data. In essence, ViewModel acts as a coordinator between View and Model.
  • View - View deals only and only with appearance which one sees on the screen. As a best practice, there should be no logic code in View classes, which need to be tested by unit test. In simple words, Views are meant only for UI visual behavior.

I hope, till now, you might have got an idea of what is the responsibility of View, ViewModel and Model. Well, now before jumping onto the coding part, I would like to brief you about some other points as well, which need to be handled for better and cleaner implementation of MVVM.

Important Components of Any MVVM App

There are two main components which play a very vital role in implementing any application with MVVM. The first one is base class for ViewModel and the second one is ICommand interface.

Base Class - There is some common stuff which is required for each and every ViewModel. So, in order to follow the good design, those common things should be placed in a base class and further this class can be derived by various ViewModels. Now the question is, what this base class should contain?

This base class contains the implementation of INotifyPropertyChanged interface. As I mentioned earlier, ViewModel cannot reference View directly. So, this interface bridges the gap between two and allows the messages to be passed to the View. The sample implementation of INotifyPropertyChanged is:

C#
public class ViewModelBase:INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged(string prop)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }
    }
} 

Please note, the above snippet is the basic one. So, if required, it can be expanded in various ways like addition of various validations like property name check, etc.

Well, let's move to ICommand interface.

ICommand Interface - This interface provides very useful methods like Execute and CanExecute, which gives full control on commanding part. Commands are used by View to interact with ViewModel. Sample code is:

C#
public class DelegateCommand : ICommand
{
     private Action<object> _action;
     public DelegateCommand(Action<object> action)
     {
         _action = action;
     }

    #region ICommand Members
    public event EventHandler CanExecuteChanged;
    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _action(parameter);
    }

    #endregion
}

I hope this much knowledge is enough to proceed with a simple MVVM example.

Example Scenario

This is the example of Student entity and to keep it simple, I am taking only FirstName of a student. The list of students will be displayed on the screen. If user will select student name from the list and clicks on given button, then the selected name will be displayed in the textbox shown below. Isn't it simple???

Model

As I told, my model class is very simple here with 2 lines of code:

C#
public class Student
{
    public string FirstName { get; set; }
}

ViewModel

This class is bit complex than our Model. First let's have a look at the below snippet, then I'll talk more about it:

C#
public class StudentsViewModel:ViewModelBase
{    
    public ObservableCollection<Student> StudentList { get; set; }
    public string SelectedStudent { get; set; }

    private ICommand _updateStudentNameCommand;
    public ICommand UpdateStudentNameCommand
    {
        get { return _updateStudentNameCommand; }
        set { _updateStudentNameCommand = value; }
    }       
    private string _selectedName;
    public string SelectedName 
    {
        get { return _selectedName; }
        set
        {
            if (_selectedName != value)
            {
                _selectedName = value;
                RaisePropertyChanged("SelectedName");
            }
        }
    }
    
    public StudentViewModel()
    {
        UpdateStudentNameCommand = new DelegateCommand(new Action<object>(SelectedStudentDetails));
        StudentList = new ObservableCollection<Model.Student> 
        { 
                new Student { FirstName = "Bruce" },
                new Student { FirstName = "Harry" },
                new Student { FirstName = "Stuart" },
                new Student { FirstName = "Robert" }
        };           
      }


    public void SelectedStudentDetails(object parameter)
    {
        if (parameter != null)
            SelectedName = (parameter as SimplestMVVM.Model.Student).FirstName;
    }
}

You might have noticed that we are inheriting ViewModelBase class, which provides the implementation of INotifyPropertyChanged. Here I am exposing properties like FirstName, StudentList, and UpdateDetailsCommand which view can bind to.

Well, let's take this one-by-one.

  • FirstName - This property is used to bind individual items of my ListView
  • StudentList - This property contains the list of first names and is set as a ItemSource of my ListView
  • UpdateDetailsCommand - This property returns an ICommand using DelegateCommand class. This can be bound to anything like button press or key press. I hooked this command to my method UpdateStudentDetails on button press, in order to update the text.

That's all about the viewmodel. Now we can proceed to the UI drawing.

View

Coming to view, by code behind is totally empty:

C#
public MainWindow()
{
    InitializeComponent();
}

And most of the UI related stuff is placed in the XAML file itself:

XML
<Window x:Class="SimplestMVVM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SimplestMVVM.ViewModel"
        Title="MVVM" Height="300" Width="300">
    <Window.DataContext>
        <local:StudentsViewModel x:Name="ViewModel"/>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="0.878*"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
         </Grid.ColumnDefinitions>
                <StackPanel Grid.RowSpan="2">
        <ListView Name="ListViewStudentDetails" 
               Grid.Row="2" ItemsSource="{Binding StudentList}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name" 
                         DisplayMemberBinding="{Binding FirstName}"/>
                </GridView>
            </ListView.View> 
         </ListView>
        <Button Command="{Binding UpdateStudentNameCommand}" 
          CommandParameter="{Binding ElementName=ListViewStudentDetails,Path=SelectedItem}"  
          Content="Display selected student"/>
        <TextBlock FontWeight="Bold" Text="Selected student is: ">
          <Run Text="{Binding SelectedName, Mode=TwoWay}"/></TextBlock>
        </StackPanel>
    </Grid>
</Window>

If you will see the code carefully, you will get a clear idea about the properties I mentioned in ViewModel.

And that's all the simplest ever MVVM sample. All together around with very few lines of code. Isn't it good???

Future Plan

In my next post, I will discuss more about the different aspects of MVVM.

Relevant Tracks

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
QuestionThis is simple example but... Pin
Member 130397161-May-21 22:09
Member 130397161-May-21 22:09 
PraiseSimple Indeed! Pin
Member 1109582021-Jun-16 11:49
Member 1109582021-Jun-16 11:49 
GeneralUpdateDetailsCommand Pin
LOKImotive22-Nov-13 14:49
LOKImotive22-Nov-13 14:49 
GeneralRe: UpdateDetailsCommand Pin
Shweta Lodha23-Nov-13 8:12
Shweta Lodha23-Nov-13 8:12 
Thanks for pointing it out. I'll rectify it.
Regards,
Shweta Jain
http://www.shwetalodha.blogspot.in/

QuestionMy vote of 3 Pin
Richard MacCutchan13-Nov-13 2:23
mveRichard MacCutchan13-Nov-13 2:23 
AnswerRe: My vote of 3 Pin
Shweta Lodha13-Nov-13 5:51
Shweta Lodha13-Nov-13 5:51 
GeneralRe: My vote of 3 Pin
Richard MacCutchan13-Nov-13 6:18
mveRichard MacCutchan13-Nov-13 6:18 
GeneralMy vote of 4 Pin
Winner7812-Nov-13 23:53
Winner7812-Nov-13 23:53 
GeneralRe: My vote of 4 Pin
Shweta Lodha13-Nov-13 1:20
Shweta Lodha13-Nov-13 1:20 
GeneralMy vote of 5 Pin
M Rayhan10-Nov-13 19:03
M Rayhan10-Nov-13 19:03 
GeneralRe: My vote of 5 Pin
Shweta Lodha12-Nov-13 9:54
Shweta Lodha12-Nov-13 9:54 
GeneralMy vote of 4 Pin
Paulo Zemek10-Nov-13 2:45
mvaPaulo Zemek10-Nov-13 2:45 
QuestionStudentViewModel or StudentsViewModel? Pin
Paulo Zemek10-Nov-13 2:25
mvaPaulo Zemek10-Nov-13 2:25 
AnswerRe: StudentViewModel or StudentsViewModel? Pin
Shweta Lodha12-Nov-13 9:53
Shweta Lodha12-Nov-13 9:53 
GeneralMy vote of 1 Pin
Bill S9-Nov-13 5:35
professionalBill S9-Nov-13 5:35 
GeneralRe: My vote of 1 Pin
Klaus Luedenscheidt9-Nov-13 17:11
Klaus Luedenscheidt9-Nov-13 17:11 
GeneralRe: My vote of 1 Pin
Shweta Lodha9-Nov-13 22:24
Shweta Lodha9-Nov-13 22:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.