first_page

More Flippant Remarks about MVVM

My last note marked a first attempt to capture MVVM. This is the second try to gain intimate understanding. I start with this:

You can easily tell WPF how to render a ViewModel object by using typed DataTemplates. A typed DataTemplate does not have an x:Key value assigned to it, but it does have its DataType property set to an instance of the Type class. If WPF tries to render one of your ViewModel objects, it will check to see if the resource system has a typed DataTemplate in scope whose DataType is the same as (or a base class of) the type of your ViewModel object. If it finds one, it uses that template to render the ViewModel object referenced by the tab item’s Content property.

The meaning in the previous, Josh-Smith paragraph can be summarized by his source code: <DataTemplate DataType="{x:Type vm:CustomerViewModel}">

<vw:CustomerView />

</DataTemplate> The XAML DataTemplate element is “typed” because it has a DataType attribute pointing to a View Model. This declaration is, here in the rasx() context, the heart of MVVM. Almost everything around this kind of XAML markup is the wiring that Microsoft should make go away in future versions of WPF. Now, more flippant remarks:

  • It is not unhealthy (for me) to see similarities between ASP.NET MVC strongly-typed model binding and strongly-typed WPF DataTemplate declarations.
  • It may seem strange that WPF will load a View based on binding to a View Model. So here is a near unique case of data driving visual presentation.
  • The ObservableCollection<(Of <(T>)>) can be used in the View Model to allow changes in groups of data to be tracked by WPF conventions.
  • DependencyProperty is used for single data items like the ObservableCollection.
  • Of course, Plain-old .NET data classes can be used with WPF but you don’t get stuff like two-way binding for free. Josh Smith shows you what you have to pay (not much to me) by implementing a class around INotifyPropertyChanged.
  • When “commanding” in WPF we are discouraged from working with RoutedCommand. We should implement our own class around ICommand. Josh Smith, an amazing guy, shows us how this is done.

rasx()