Yippy – the F# MVVM Pattern

Posted by MarkPearl on Geeks with Blogs See other posts from Geeks with Blogs or by MarkPearl
Published on Thu, 17 Jun 2010 00:04:38 GMT Indexed on 2010/06/16 23:12 UTC
Read the original article Hit count: 335

Filed under:

 

I did a recent post on implementing WPF with F#. Today I would like to expand on this posting to give a simple implementation of the MVVM pattern in F#. A good read about this topic can also be found on Dean Chalk’s blog although my example of the pattern is possibly simpler.

With the MVVM pattern one typically has 3 segments, the view, viewmodel and model. With the beauty of WPF binding one is able to link the state based viewmodel to the view. In my implementation I have kept the same principles. I have a view (MainView.xaml), and and a ViewModel (MainViewModel.fs).

 

2010-06-17 12-50-01 AM

 

What I would really like to illustrate in this posting is the binding between the View and the ViewModel so I am going to jump to that…

In Program.fs I have the following code…

module Program

open System
open System.Windows
open System.Windows.Controls
open System.Windows.Markup
open myViewModels

// Create the View and bind it to the View Model
let myView = Application.LoadComponent(new System.Uri("/FSharpWPF;component/MainView.xaml", System.UriKind.Relative)) :?> Window
myView.DataContext <- new MainViewModel() :> obj

// Application Entry point
[<STAThread>]
[<EntryPoint>]
let main(_) = (new Application()).Run(myView)
    
    

You can see that I have simply created the view (myView) and then created an instance of my viewmodel (MainViewModel) and then bound it to the data context with the code…

myView.DataContext <-

new MainViewModel() :> obj

If I have a look at my viewmodel (MainViewModel) it looks like this…

module myViewModels
open System
open System.Windows
open System.Windows.Input
open System.ComponentModel
open ViewModelBase

type MainViewModel() =          
    // private variables
    let mutable _title = "Bound Data to Textbox"    

    // public properties
    member x.Title 
        with get() = 
                _title 
        and set(v) = 
                _title <- v

    // public commands
    member x.MyCommand = 
        new FuncCommand
            (
                (fun d -> true), 
                (fun e -> x.ShowMessage) 
            )

    // public methods
    member public x.ShowMessage = 
        let msg = MessageBox.Show(x.Title)
        ()    

I have exposed a few things, namely a property called Title that is mutable, a command and a method called ShowMessage that simply pops up a message box when called.

If I then look at my view which I have created in xaml (MainView.xaml) it looks as follows…

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="F# WPF MVVM" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBox Text="{Binding Path=Title, Mode=TwoWay}" Grid.Row="0"/>
        <Button Command="{Binding MyCommand}" Grid.Row="1">
            <TextBlock Text="Click Me"/>
        </Button>
    </Grid>
</Window>

2010-06-17 12-56-50 AM

 

It is also very simple. It has a button that’s command is bound to the MyCommand and a textbox that has its text bound to the Title property.

One other module that I have created is my ViewModelBase. Right now it is used to store my commanding function but I would look to expand on it at a later stage to implement other commonly used functions…

module ViewModelBase

open System
open System.Windows
open System.Windows.Input
open System.ComponentModel

type FuncCommand (canExec:(obj -> bool),doExec:(obj -> unit)) =
    let cecEvent = new DelegateEvent<EventHandler>()
    interface ICommand with
        [<CLIEvent>]
        member x.CanExecuteChanged = cecEvent.Publish
        member x.CanExecute arg = canExec(arg)
        member x.Execute arg = doExec(arg)

Put this all together and you have a basic project that implements the MVVM pattern in F#.

2010-06-17 01-00-04 AM

For me this is quite exciting as it turned out to be a lot simpler to do than I originally thought possible. Also because I have my view in XAML I can use the XAML designer to design forms in F# which I believe is a much cleaner way to go rather than implementing it all in code. Finally if I look at my viewmodel code, it is actually quite clean and compact…

© Geeks with Blogs or respective owner