Model-View-ViewModel pattern example


I’ve been promising an example of the Model-View-ViewModel pattern for some time.  With the Feb CTP of WinFX out and the Feb CTP of Expression Interactive Designer close, I feel like I can post something that will work for awhile.  I had more ambitious plans for a complex, real-world example, but realized that 1)  I didn’t have much time to write such a beast and 2)  It was hard to create a complex example that still clearly explained the principles. 


So, I came up with the idea of doing a toy contact database.  The core model classes looks like this:






public class Contact
{
// Methods
public Contact(string name, Gender gender, string favoriteColor);
public override string ToString();

// Properties
public string FavoriteColor { get; }
public Gender Gender { get; }
public string Name { get; }
}






public class ContactDatabase
{
// Events
public event ContactsChangedEventHandler ContactDatabaseChanged;

// Methods
public ContactDatabase();
public void AddContact(Contact newContact);
private void OnContactDatabaseChanged(ContactsChangedType changeType, int index, Contact contact);
public void RemoveContact(int index);

// Properties
public Contact> Contacts { get; }
}


Notice the classes have no special WPF dependencies.  Imagine this is a pre-existing model, perhaps an interchange schema or a web-service with no UI or specific UI technology in mind.  What I will be demonstrating is how to wrap this Model in a ViewModel an then build a UI on that ViewModel, all without changing the Model and especially without mixing UI code into it.


But to start, I want to show how much you can do with WPF data binding to just bind directly to the model…without any additional code.  It turns out, quite alot.  Here’s a scrap of XAML I created using Expression:


 <!– The code will set the data context for this item –>
 <Grid  x:Name=”MasterDetailContainer”
   Margin=”28,25,28,11″ RenderTransformOrigin=”0.5,0.5″>
  <Grid.ColumnDefinitions>
   <ColumnDefinition Width=”0.45*”/>
   <ColumnDefinition Width=”0.55*”/>
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
   <RowDefinition/>
  </Grid.RowDefinitions>
  
  <!– The parent’s data context is going to be of type ContactDatabase
       we bind the ListBox items to the ContactDatabase.Contacts property –>
  <ListBox x:Name=”ContactsListBox”
    Margin=”12,12,11,94″ RenderTransformOrigin=”0.5,0.5″
    ItemsSource=”{Binding Path=Contacts}”
  
    IsSynchronizedWithCurrentItem=”True”/>
    
  <ContentControl  x:Name=”CurrentContactDetail”
    Margin=”14,16,17,219″ Grid.Column=”1″ RenderTransformOrigin=”0.5,0.5″
    Content=”{Binding Items.CurrentItem, ElementName=ContactsListBox, Mode=OneWay}”/>
    
    
  <Button x:Name=”AddButton”
    HorizontalAlignment=”Left” VerticalAlignment=”Bottom” Margin=”18,0,0,131″
    Width=”86″ Height=”58″ Grid.Column=”1″ RenderTransformOrigin=”0.5,0.5″
    Content=”Add”
    IsEnabled=”false”/>
  <Button x:Name=”RemoveButton”
    HorizontalAlignment=”Stretch” VerticalAlignment=”Bottom” Margin=”135,0,93,131″
    Width=”86″ Height=”58″ Grid.Column=”1″ RenderTransformOrigin=”1,0.48″
    Content=”Remove”
    IsEnabled=”false”/>
 </Grid>


The full project code at this point is attached.  Take a look at it.  In the next installment I will add a simple ViewModel.

ContactViewModel0.zip


Comments (5)

  1. John Gossmann has posted the first part of his long-awaited example of a Model-View-ModelView architecture,…

  2. ViewModel says:

    I fail to see the relevance of this, post the ViewModel already!!

  3. Jag talar ofta med kunder och partners som vill använda vedertagna designmönster för att separera ansvaret