Awesome application

I presented Update Controls in WPF, Silverlight, and Winforms online for a bunch of folks not at PDC. You can download the source code and watch the recording to follow along.

The most awesome app ever
The most awesome app ever is Excel. Actually, it’s Excel’s great grandfather VisiCalc. With these apps you express the relationship among parts of your data. The spreadsheet figures out when to recalculate and keep things up to date.

You can demonstrate the View Model pattern in Excel. Put your name in C1. That’s the data model. Then enter the formula “=C1” into B1. That’s the view model. It gets its data from the data model. It doesn’t store that data, it just interprets it for the benefit of a specific view. Finally, put the formula “=B1” into A1. This is your view. It binds to properties of your data model. It can’t do complex logic. That’s the View Model’s job.

I want to write my application the same way that I construct a spreadsheet. It should just know what depends upon what, and keep things up to date. That’s what I demonstrate with Update Controls.

Don’t copy data
The View Model does not make a copy of your data. It delegates to the Data Model. If data is stored in two places, it might get out of sync. If it’s stored in only one place, then there is no chance of inconsistency.

The View Model in this example does not have any fields, other than the references that are assigned during construction. If you are storing state in your data model, you are probably making a mistake. If that state is a copy of what’s in the Data Model, or it can be calculated from the Data Model, then delegate. If not consider moving it to a navigation model.

Navigation model
Your application exists for one purpose: to manage information in a specific problem domain. That is what goes into the Data Model. Everything else is there to help the user navigate through that information. That goes into the Navigation Model.

The Navigation Model keeps track of selected items. The selected item of a ListBox is bound to a property on the View Model. That property just delegates to the Navigation Model. Putting the user selection into the Navigation Model instead of directly binding controls to one another allows you to programmatically change the selection. All you do is change the property in the Navigation Model.

The Navigation Model also keeps track of search parameters. A TextBox is bound to a Filter property, which delegates to the Navigation Model. A where clause in the linq query in the View Model compares items to this Filter. Since the linq query references the Filter property, the list is dependent upon it. Changing the Filter updates the list.

Rapidly added features
Update Controls discovers dependencies for you. You don’t have to manage dependencies on your own. When you do your own dependency management, you have to touch old code to add a new feature. But when the system manages dependencies, you can add new code and the old code will continue to behave as expected. All you have to do is:

  • Store domain data in the Data Model.
  • Store user selection and navigation in the Navigation Model.
  • Delegate from the View Model to either the Data or the Navigation Model: don’t store state in the View Model.
  • Use Independent on all Data and Navigation Model fields.
  • Use ForView.Wrap() on all DataContexts that you set through code.

Comments

MVVM and NavigationModel for Windows Forms

Hi Michael

I just started to explore UpdateControl and it looks awesome so far. I'd like to ask you, is there an example of the MVVM and NavigationModel pattern for Windows Forms? What I found so far was simple binding to business objects.

thanks

MVVM and NavigationModel for Windows Forms

MVVM arose out of WPF data binding, and is not as compelling a patter for Windows Forms. WPF must data bind to properties. MVVM was a way of getting the right properties onto an object to make it suitable for data binding.

Update Controls for Windows Forms can data bind to methods, so a view model is not strictly necessary. You can put any code that you need to in a GetXxxx() event and it will work. The down side is that code in a GetXxxx() event is not testable. For anything but the most trivial of view code, you will want to move that elsewhere.

You could use a view model as your new repository of non-trivial view code. Either construct one in the view, or have one injected into the view. Let the view call its properties and methods to handle Gets and Sets. Then you can construct a view model outside of the view in order to test it.

You will find that most of the view code is trivial. You will get tired of passing all of this trivial code through the view model. So I would expose the model from the view model so that the view can access it directly when no complex logic is necessary. This is something I never do in WPF or Silverlight.

As for the navigation model, it is simply a model that is not persisted. It records the user's point-of-view as they navigate through the application. Things like UpdateListBox.SetSelectedItem() should write to the navigation model, and then other controls can read from it.

I haven't written up an MVVM sample for Windows Forms because the pattern doesn't always apply. My simple examples don't require a view model, and adding one would just clutter them. But for complex Windows Forms applications, I have introduced view models and navigation models.

MVVM and NavigationModel for Windows Forms

Thank you for the detailed answer. Just one more question. If I understand correctly, with UpdateControls there is no need to use BindingSource in controls to communicate with the view model. Isn't it very cumbersome to write the OnGet/OnSet event handlers for all controls, or you use UpdateControls only for dependent controls?

Event handlers vs. control properties

You are correct. You don't need to set BindingSource to communicate with the view model. The Get and Set event handlers just need to reference the view model.

I find writing Get/Set events to be a reasonable trade-off. I'll even do that if my form does not exhibit inter-dependency.

The traditional way of working with Windows Forms applications is to load up control properties with initial values when the form loads, and then copy the values out of those properties when you're done. The control properties store your user's data while they work with it.

The Update Controls way is to bind the controls to the model (possibly through a view model) with the Get/Set events. The model stores your user's data, not the control properties.

I find this to be a reasonable trade-off because I don't have to write the load/unload code. It ends up being more lines-of-code to say the same thing, but it gives me the flexibility to add inter-dependent behavior later should I need it.