1 Basics

First we discuss the Rules for MVVM
Next we discuss the technologies present in WPF that enable MVVM to florish. 
Only one thing comes to mind. 
  • DataBinding
Really!

The Rules for MVVM. 

The objective is simple. Decoupling. There should be as little behavior in your view (beyond it being pretty and bouncy) as possible.
This means that if: 
  • There is the model, 
  • the view (xaml and its associated codebehind)
  • viewmodel

The View will interact will the ViewModel through non GUI related ways (i.e. code behind is bad) and the ViewModel will handle the Model for the View.
I think its pretty simple. Don't get it? Just a few more paragraphs and not only will you "get" it. You will "do" it. 

Tech for MVVM built into WPF

Databinding

Check out the Basics1 application. All that the application contains is a single window with a View - ViewModel (the model is ignored for now) 



Lets stop talking in words and Jump to code. We will make a simple application where the objective is just to edit some text. Our only objective is to do it with data binding. I recommend you download the project Basics1 
All that I did for it after "Setting up a project to use cinch"  is I used snippet to add a string MainText Property to my ViewModel using a snippet. Here is the code in its Entirety (I used a cinch snippet for the region in bold): 

ViewModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

using System.ComponentModel.Composition;
using Cinch;
using MEFedMVVM.ViewModelLocator;
using MEFedMVVM.Common;


namespace Basic1
{
    [ExportViewModel("MainWindowViewModel")]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    class MainWindowViewModel : ViewModelBase
    {
        #region Property MainText
        private string _MainText;
        public static readonly PropertyChangedEventArgs _MainTextEventArgs = ObservableHelper.CreateArgs<MainWindowViewModel>(x => x.MainText);
        public string MainText
        {
            get { return _MainText; }
            set
            {

                if (object.ReferenceEquals(_MainText, value)) return;
                _MainText = value;
                NotifyPropertyChanged(_MainTextEventArgs);
            }
        }
        #endregion

        public MainWindowViewModel()
        {
        }
    }
}

And in the MainWindow.xaml the Code I added is in Bold

<Window x:Class="Basic1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:CinchV2="clr-namespace:Cinch;assembly=Cinch.WPF"
        xmlns:meffed="http:\\www.codeplex.com\MEFedMVVM"
        meffed:ViewModelLocator.ViewModel="MainWindowViewModel">
    <StackPanel>
        <TextBox Name="Main"  Text="{Binding Path=MainText, UpdateSourceTrigger=PropertyChanged}"></TextBox>
        <TextBlock Text="{Binding Path=MainText}" ></TextBlock>
    </StackPanel>
</Window>
Note: you could have also used Text="{Binding ElementName=Main,Path=Text}" rather than bind both to the same property on the ViewModel. Of course you would need to name the TextBox for it to work.

So now lets explain what I am doing: 

ViewModel Basics

All you need to use a ViewModel is to make sure that you inherit from INotifyPropertyChanged (there is also the DependencyObject but ignore my saying that). The reason this is prefered is that this Interface is a non GUI interface and your ViewModel should be free of GUI code pollution (because that is not testable witout clicking and typing and interacting and ...)

Cinch makes it easier. ViewModelBase actually inherits from INotifyPropertyChanged (amongst other things). And it warps the only event required for this interface into one of two nice functions : 

protected void NotifyPropertyChanged(PropertyChangedEventArgs args);
OR
protected void NotifyPropertyChanged(string propertyName);

Like above I could have done NotifyPropertyChanged("MainText") but the second method is better (Because you will be able to refactor your code without worrying about that string "MainText" getting left behind and there is a cool snippet that does it for your as shown: 

 

So. In short. Inherit from ViewModelBase and Use the appropriate cinch snippet for Properties. Simple really. 

View Basics 

The View Binds to the ViewModel. This is where the standard .NET Binding framework gets into play. I thing it is really simple and best explained by Visual Studio (yup! you heard right) . 
Click on TextBox in the code as shown: 

View the Text Property in Properties Window. I have clicked on the yellow icon next to Text Property and am about to click Apply Data Binding: 


The below settings correspond to the value of the Text Property (Text="{Binding Path=MainText, UpdateSourceTrigger=PropertyChanged}"): 



Notice the options available are REALLY Simple. Sincerely. There is :
  1. Source (which default to the DataContext. Which we set using MEF ViewModelLocator). The Path (which we set to MainText) 
  2. Converter (which we did not use. More on that elsewhere).
  3. Options. From which we selected that we update the source whenever the propertychanged (because the default is that the source get changed when the control loses focus). 
In case you are even slightly concerned about "Options" being weird. Don't be. There really aren't that many things there. See: 
Its really not a lot at all. I am not going to explain it all now. I just want to you be aware. What you can do with it is so very powerful. 
You might also want to check out the Source/Path/Converter tabs yourself in Visual Studio!
Till next time. Enjoy!


Comments