Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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:
Contact{ Contact( name, gender, favoriteColor); ToString(); FavoriteColor { ; } Gender { ; } Name { ; }} |
ContactDatabase{ ContactDatabaseChanged; ContactDatabase(); AddContact( newContact); OnContactDatabaseChanged( changeType, index, contact); RemoveContact( index); <> Contacts { ; }} |
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.
Comments
Anonymous
February 26, 2006
John Gossmann has posted the first part of his long-awaited example of a Model-View-ModelView architecture,...Anonymous
March 01, 2006
I fail to see the relevance of this, post the ViewModel already!!Anonymous
January 20, 2008
PingBack from http://blog.quantumbitdesigns.com/2008/01/20/wpf-application-design-and-architecture/Anonymous
July 22, 2008
PingBack from http://blog.quantumbitdesigns.com/2008/07/22/wpf-application-design-and-architecture/Anonymous
January 13, 2009
Jag talar ofta med kunder och partners som vill använda vedertagna designmönster för att separera ansvaret