Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

MVVM with WPF, Silverlight, and… Windows Forms

In my post-NTK09 conference blog post I mentioned one of my MVVM demos was about sharing a ViewModel between WPF, Silverlight and even Windows Forms application. I got a lot of requests for posting sample code online since then, which I intended to do earlier, but because the sample application code was closely related to the conference, I wanted to create a whole new sample application first and share that. Of course time passed and other things kept me busy from actually doing it. With Silverlight 4 Beta coming out recently, things progressed even further in so I decided to keep things as they were, and post the original sample code. I’ll explain it in few lines (and pictures) here, and the source code can be found here.

What’s it all about?

The purpose of the sample (and my NTK09 talk in general) was about the MVVM pattern principle and how it can be used to totally separate the User Interface from the business logic and data. The application I built was a conference session schedule viewer / editor. Technically, there are three application flavors: WPF, Silverlight and WinForms. They share the same data access (WCF service) and ViewModel. The only thing different between the three is their UI implementation.

imageimageimage

Notice the small arrow overlay over the C# icon on Silverlight and WinForms PageViewModel.cs? That’s because both project are linking the original file from the WPF project, which I created first. That means that ViewModel is exactly the same across all three projects when they are compiled. And with all three project, this is the ViewModel that serves up the main page.

The WPF project

I created the WPF project to ‘just work’. I didn’t bother with styling and the looks, I intentionally left it ugly. I used Prism for commanding and WCF based web service for communicating the data.

image

The ‘Dan’ (Day) and ‘Kategorija’ (Category) serve as the filter for the session list on the left. Each combo box change results in a server request which returns new data for filling the session list. Other fields are editable session details fields. Three buttons on the top left correspond to New, Edit and Delete, in that order.

The Silverlight project

The Silverlight project differ from WPF in that that it’s in color :)

Silverlight

Prism is still used for commanding, but the UI is quite different. I even provided the View (above) and Edit (bottom) screens.

Silverlight Edit

As said, the difference between the WPF and Silverlight applications is just and only different XAML. And both have zero code-behind code. Moving on to…

The Windows Forms project

I  didn’t bother much with making Windows Forms project to work. I last coded anything in WinForms 2+ years ago so I suspect I won’t have to go there again… However, this is the UI I put together:

Windows Forms

It’s very similar to WPF, but data bindings perform much slower. Data bindings? There’s data bindings in WinForms too?

LOL. Sometimes I really do get questions like that. Anyway, let’s see the ‘code behind’. [There’s actually quite a few lines of code behind in Windows Forms because it’s used to instantiate and initialize all controls on the screen. That code is stored in the .designer file and I’m ignoring it as the code behind]

private void MainForm_Load(object sender, EventArgs e)
{
    PageViewModel viewModel = new PageViewModel();

    dayBox.DataBindings.Add("DataSource", viewModel, "Days");
    categoryBox.DataBindings.Add("DataSource", viewModel, "Categories");
    categoryBox.DisplayMember = "Name";
    speakerBox.DataBindings.Add("DataSource", viewModel, "Speakers");
    speakerBox.DisplayMember = "FullName";
    speakerBox.ValueMember = "Id";
    startTimeBox.DataBindings.Add("DataSource", viewModel, "TimeValues");
    endTimeBox.DataBindings.Add("DataSource", viewModel, "TimeValues");
    sessionList.DataBindings.Add("DataSource", viewModel, "Sessions");
    sessionList.DisplayMember = "Title";

    dayBox.DataBindings.Add("SelectedValue", 
        viewModel, "SelectedDay", true, DataSourceUpdateMode.OnPropertyChanged);
    categoryBox.DataBindings.Add("SelectedValue", 
        viewModel, "SelectedCategory", true, DataSourceUpdateMode.OnPropertyChanged);
    sessionList.DataBindings.Add("SelectedValue", 
        viewModel, "SelectedSession", true, DataSourceUpdateMode.OnPropertyChanged);
    speakerBox.DataBindings.Add("SelectedValue", 
        viewModel, "SelectedSession.SpeakerId", true, DataSourceUpdateMode.OnPropertyChanged);

    startTimeBox.DataBindings.Add("Text", 
        viewModel, "SelectedSession.StartTime", true, DataSourceUpdateMode.OnValidation);
    endTimeBox.DataBindings.Add("Text", 
        viewModel, "SelectedSession.EndTime", true, DataSourceUpdateMode.OnValidation);
    titleBox.DataBindings.Add("Text", 
        viewModel, "SelectedSession.Title", true, DataSourceUpdateMode.OnValidation);
    descriptionBox.DataBindings.Add("Text", 
        viewModel, "SelectedSession.Description", true, DataSourceUpdateMode.OnValidation);

    newButton.Click += (s, ev) => 
        { viewModel.NewSessionCommand.Execute(null); };
    editButton.Click += (s, ev) => 
        { viewModel.EditSessionCommand.Execute(viewModel.SelectedSession); };
    deleteButton.Click += (s, ev) => 
        { viewModel.DeleteSessionCommand.Execute(viewModel.SelectedSession); };
    saveButton.Click += (s, ev) => 
        { viewModel.EndEditSessionCommand.Execute(viewModel.SelectedSession); };
    cancelButton.Click += (s, ev) => 
        { viewModel.CancelEditSessionCommand.Execute(viewModel.SelectedSession); };
}

This is all the code for the main form. You’ll notice it’s all used for binding controls to various properties on the ViewModel. I could also get rid of some of the lines by setting the properties on the WinForms designer (thus moving them to the .designer file). The last section wires button clicks to execute commands in the ViewModel.

There is absolutely no business logic in this code which makes it very similar to declarative XAML in WPF and Silverlight projects. I was toying with the idea of making an Extender Provider to get rid of the above lines completely and do it all just with the Windows Forms designer – I made a working prototype, but wasn’t generic enough to include it in the sample.

Source code

Bellow is the full source for all three main and related projects. Also included is the Test project with a few Silverlight Unit Test Framework tests. Database is not included so you’ll not be able to actually run any of the applications. Sorry. I’ll post the Silverlight version online when time permits.