React: What WPF Should Have Been

I’ve been learning and using React, and I like it’s general approach to building UIs. I really like the unidirectional data flow, though I’m still on the fence about virtual DOM. I get the benefits and really like that it makes testing really easy. However, I am not sold on its being unquestionably better than directly manipulating the DOM or Google’s Incremental DOM. Nevertheless, React, Om, Elm, and others have proven it a viable and fast approach.

One of the best advantages of the aforementioned frameworks is they all allow you to compose custom, reusable elements or components building off of existing HTML elements. (I think WebComponents allows something similar, though I have not personally liked its direction.) Another advantage is that you can declare all these things within JavaScript or your transpiler of choice.

I liked many similar attributes of WPF and XAML when I worked on desktop software. At that time, I had just taken a job doing .NET consulting and was still learning .NET. I had mostly tinkered with VB6, PHP, Ruby, Python, SVG, and XForms to build desktop and web applications. I really enjoyed adding SVG and XForms into web apps to make them richer, though I never quite mastered either and, at the time, both required plugins that didn’t often play well together. XAML offered a chance to do something similar with desktop applications, and I enjoyed it a lot.

However, I worried that Microsoft had opted to build their own markup language when so many, similar languages already existed and offered a nice composition story. Also, I recall thinking that the previous strategy of walled gardens appeared ready to collapse. Fast forward a few years, and Web Standards were alive and well in the form of HTML5 (with SVG baked in) as Chrome and Firefox began picking up market share, and XAML was isolated to the Microsoft platform. A few other vendors had similar markup language efforts, all of which remained isolated to their own platforms.

Imagine, if you will, a different scenario. Had Microsoft been prescient enough to see the revival and adoption of HTML and SVG and built WPF on top of these, do you think things would have gone differently? XAML had features of XForms without the complexity. XForms didn’t survive, so it is possible that a XAML built on HTML and SVG with some of the XForms-like features could perhaps have been the baseline for HTML5. Microsoft developers would have a single UI platform to write web and desktop applications.

One can dream.

The one thing Microsoft didn’t solve was the unidirectional data flow. I’m not sure they would have solved that. Data binding was and still is a popular approach. I dislike it b/c I’ve so often been bitten by refactoring things and those refactorings not making it into the UI markup templates. However, XAML didn’t require the markup file; you could/can also create those elements in your programming language. I first encountered the unidirectional style in a sample F# WPF application. There is no JSX equivalent, but the unidirectional data flow, immutable values, and all the rest are certainly possible. Yet WPF is still primarily known more for its data-binding abilities and preferred MVVM than for its flexibility in allowing different styles of development.

I can imagine an alternative reality in which React was just a JavaScript implementation of something realized first by Microsoft in .NET. Unfortunately, that didn’t happen. Nevertheless, one could write a set of elements for WPF to mimic HTML and SVG and then layer on a version of React, were one of a mind to do so. Even if not, you may still find it useful to give F# a try in order to mimic the same unidirectional data flow you can find in React. You can see an example in the recent Community for F# recording with Phil Trelford on F# on the Desktop.

Advertisements

Jaime Rodriguez on MIX 09 Silverlight News

I enjoyed reading Jaime Rodriguez’s thoughts on the Silverlight news from MIX 09. Very good info; however, I still think that most WPF apps will begin moving to Silverlight unless those additional features are needed. In most layered architectures, workflows, et. al. are created and used in the service layer, not the presentation layer. Silverlight as Moonlight is also the only option for Mono compiled apps, and I don’t believe the Mono Project plans on adding WPF in full. So for complete cross-platform re-use, you’ll need to stick to Silverlight.

WPF DataBinding: Nullable Value Types

We recently ran into what appeared to be an inconsistency in WPF’s data binding. When you attempt to data bind to a nullable value type with a value of null, WPF appears to drop the binding. Using an identity converter and several other methods only told us what we already knew, so I did a little research this morning.

hortha posted a solution with examples to the MSDN Code Gallery that we tried this morning. His solution works beautifully. Several commenters noted that VS2008 SP1 is supposed to fix this without converters, but no one seems to have tried it.

WPF DataBinding: Refreshing from Source

WPF DataBinding is terrific and allows for very passive views and easy source object updates. However, triggering updates in the view based on changes in the source object can be a little tricky.

If you want to make sure changes to your source object are reflected in your view, your source object will need to implement INotifyPropertyChanged (see example). Yet just implementing this property will not necessarily update your bindings. If your source object includes collections, and you bind to properties in those collections, you can update the source property but will not get updates from the source property, even if it is of a type that implements INotifyPropertyChanged.

The above scenario is common with Linq to Sql when the entities are generated for you. Even tables with one-to-one mappings will be generated with lists–as SQL doesn’t have a way of representing one-to-one relationships–so be sure to edit your dbml accordingly in order to take advantage of binding to your source object’s properties. (You might also consider removing some relationships to remove issues with DataContext collisions when trying to set properties of one Linq entity to another.)

If you can’t fix the problem this way or want to display the collection and changes to the collection, you can always add an ObservableCollection to your PresentationModel or wrap the source object with another object that does use the ObservableCollection to display your collection.

Composite WPF Patterns

Microsoft’sComposite Application Guidance for WPF (Composite WPF) gives WPF a lightweight yet effective application block with which to build exciting applications. However, the biggest struggle is deciding on a pattern for applying the library. The Model-View-ViewModel (MVVM), mentioned across the web as the perfect pattern for implementing MVC with WPF, was for some reason not specifically mentioned in the Composite WPF documentation. Nevertheless, the MVVM pattern is many times used and alluded to under the name PresentationModel and is arguably the best approach in most cases.

Dan Crevier posted a series of excellent articles defining the pattern and giving examples of the implementation of MVVM in WPF. These were written several years ago, before development of the Composite WPF block, but they are simple to understand and can give added understanding to the objects included in Composite WPF. For example, his post on encapsulating commands is very similar to the DelegateCommand object provided with CompositeWPF, though the latter uses lambdas to define Execute and CanExecute methods, whereas the former uses a base class and inheritance to define the methods. Using Dan’s example, the equivalent DelegateCommand, contained within the DelegateCommand’s definition, would look something like this:

public DelegateCommand<object> MyCommand { get; private set; }

public Window1()
{
    InitializeComponent();
    MyCommand = new DelegateCommand<object>(
        p => {
                 string text = p as string;
                 // Do something with text
             },
        p => !string.IsNullOrEmpty(p as string));
}

Dan’s definitions of the Model, which he calls DataModel, View and ViewModel match very closely with Composite WPF’s PresentationModel pattern. In this case, the DataModel is a representative object that is fit for display within the View. Using the entities generated for Linq to SQL, you might add properties to the partial classes create the necessary properties to which to bind. These classes should also implement INotifyPropertyChanged so that other DataModels can respond to changes from another, related View and update their data accordingly.

The View should use bindings for everything. The beauty of WPF is truly in its DataBinding functionality. The observer pattern is built right into the Binding, so that whenever one view changes, other views are notified by their bindings to their DataModels. Even the actions to be performed on a user interaction with the UI can be removed to the ViewModel, DataModel, or in the case of Composite WPF, a controller, Shell, or App level, as appropriate. This leaves the View looking very passive, indeed, which greatly helps when unit testing.

The ViewModel is the actual PresentationModel. It hosts the DataModel, as well as the View’s commands. ViewModel should be the object used to bind to the View’s DataContext and should implement INotifyPropertyChanged if any of the properties could change. The QuickStarts and RIStockTrader examples provide excellent samples of the PresentationModel, though be warned that the examples often use different patterns, if for no other reason than to show other pattern implementations.

That covers the MVVM pattern. However, there’s one more aspect that needs to be covered: composite regions. Composite WPF provides regions for managing the display of different modules in the Shell, but what if you need to display multiple modules or views within a “summary” view that is already on the Shell? In this case, you can use a Controller to manage the child use cases. The UIComposition QuickStart shows a terrific example of creating a controller in a ViewModel for the purposes of managing child use cases. This removes the dependencies and depth of a View that includes a tab control containing a large number of child use cases. (The UIComposition QuickStart uses a Supervising Controller pattern instead of the PresentationModel/MVVM pattern, so you’ll have to adjust it accordingly, but it works beautifully.)

The MVVM pattern is a great solution for WPF applications by allowing WPF’s DataBinding and Commanding to remove much of the logic formerly found in the View layer out to a unit testable ViewModel. The architecture stays clean and also fairly shallow in that an additional Presenter class is unnecessary (as opposed to the Supervising Controller pattern.)

Additional Resources:
John Grossman – Tales from the Smart Client
Pete Weissbrod – Model-View-ViewModel Pattern for WPF: Yet Another Approach