This topic illustrates how to exploit Functional Programming in a WPF application. The first example comes from a post by Māris Krivtežs (ref Remarks section at the bottom). The reason for revisiting this project is twofold:
1\ The design supports separation of concerns, while the model is kept pure and changes are propagated in a functional way.
2\ The resemblance will make for an easy transition to the Gjallarhorn implementation.
I feel that none of these XAML application
styles benefit much from functional programming. I imagine that the
ideal application would consist of the view which produces events and
events hold current view state. All application logic should be
handled by filtering and manipulating events and view model, and in
the output it should produce a new view model which is bound back to
Our demo app consists of a scoreboard. The score model is an immutable record. The scoreboard events are contained in a Union Type.
Changes are propagated by listening for events and updating the view model accordingly. Instead of adding members to the model type, as in OOP, we declare a separate module to host the allowed operations.
Our view model derives from EventViewModelBase<'a>, which has a property EventStream of type IObservable<'a>. In this case the events we want to subscribe to are of type ScoringEvent.
The controller handles the events in a functional manner. Its signature Score -> ScoringEvent -> Score shows us that, whenever an event occurs, the current value of the model is transformed into a new value. This allows for our model to remain pure, although our view model is not.
An eventHandler is in charge of mutating the state of the view. Inheriting from EventViewModelBase<'a> we can use EventValueCommand and EventValueCommandChecked to hook up the events to the commands.
The code behind file (*.xaml.fs) is where everything is put together, i.e. the update function (controller) is injected in the MainViewModel.
The type CompositionRoot serves as a wrapper that’s referenced in the XAML file.
I won’t dive any deeper into the XAML file as it’s basic WPF stuff, the entire project can be found on GitHub.
The core types in the Gjallarhorn library implement IObservable<'a>, which will make the implementation look familiar (remember the EventStream property from the FSharp.ViewModule example). The only real change to our model is the order of the arguments of the update function. Also, we now use the term Message instead of Event.
In order to build a UI with Gjallarhorn, instead of making classes to support data binding, we create simple functions referred to as a Component. In their constructor the first argument source is of type BindingSource (defined in Gjallarhorn.Bindable), and used to map the model to the view, and events from the view back into messages.
The current implementation differs from the FSharp.ViewModule version in that two commands do not have CanExecute properly implemented yet. Also listing the application’s plumbing.
Left with setting up the decoupled view, combining the MainWindow type and the logical application.
This sums up the core concepts, for additional information and a more elaborate example please refer to Reed Copsey’s post. The Christmas Trees project highlights a couple of benefits to this approach:
Effectively redeeming us from the need to (manually) copy the model
into a custom collection of view models, managing them, and manually
constructing the model back from the results.
Updates within collections are done in a transparent manner, while maintaining a pure model.
The logic and view are hosted by two different projects, emphasizing the separation of concerns.
This modified text is an extract of the original Stack Overflow Documentation created by following contributors and released under CC BY-SA 3.0