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

Skip to main content