The Model-View-ViewModel (MVVM or ViewModel) is a pattern for separating concerns in technologies that use databinding. For Silverlight 2, it can help to make more maintainable applications by removing much of the code in the code-behind files and allowing full testing of business logic. This video shows how to do a simple implementation of MVVM in Silverlight 2 without additional helpers (like Prism, Silverlight.FX, etc.).
public class GameCatalog : IGameCatalog
{
Uri theServiceRoot;
GamesEntities theEntities;
const int MAX_RESULTS = 50;
public GameCatalog() : this(new Uri("/Games.svc", UriKind.Relative))
{
}
public GameCatalog(Uri serviceRoot)
{
theServiceRoot = serviceRoot;
}
public interface IGameCatalog
{
void GetGames();
void GetGamesByGenre(string genre);
void SaveChanges();
event EventHandler<GameLoadingEventArgs> GameLoadingComplete;
event EventHandler<GameCatalogErrorEventArgs> GameLoadingError;
event EventHandler GameSavingComplete;
event EventHandler<GameCatalogErrorEventArgs> GameSavingError;
}
public ObservableCollection<Game> Games
{
get
{
return theGames;
}
}
public GamesViewModel(IGameCatalog catalog)
{
theCatalog = catalog;
theCatalog.GameLoadingComplete +=
new EventHandler<GameLoadingEventArgs>(games_GameLoadingComplete);
theCatalog.GameLoadingError +=
new EventHandler<GameCatalogErrorEventArgs>(games_GameLoadingError);
}
<UserControl.Resources>
<data:GamesViewModel x:Key="TheViewModel"
d:IsDataSource="True" />
</UserControl.Resources>
void genreComboBox_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
string item = genreComboBox.SelectedItem as string;
if (item != null)
{
LoadGames(item);
}
}
[TestMethod]
[Description("Test Successful LoadGamesByGenre from the ViewModel")]
[Asynchronous]
public void TestLoadGamesByGenre()
{
bool loadComplete = false;
GamesViewModel viewModel = new GamesViewModel(new MockGameCatalog());
viewModel.LoadComplete += (s, e) =>
{
loadComplete = true;
};
viewModel.LoadGamesByGenre("Family");
EnqueueConditional(() => loadComplete);
EnqueueCallback(() =>
{
Assert.AreNotEqual(viewModel.Games, null, "Expected games list not to be null.");
});
EnqueueCallback(() =>
{
Assert.IsTrue(viewModel.Games.Count > 0, "Expected games list have results.");
});
EnqueueTestComplete();
}
This article forms the basis for the screencast. It gives a great walkthrough of the need for the MVVM pattern and the implementation of the pattern.
This is the companion code to the article. It's a clean, open source implementation of the ViewModel pattern.
Shawn's blog is a great source of Silverlight (and other) information.
This is an open source testing framework for Silverlight. It's recommended for any Silverlight project.