F# And MVVM – A Simple ViewModel

by Dean 12. April 2010 20:51

For many years, OOP abstractions and design patterns have been the cornerstones of my development methodology as a senior C# developer in investment banking.

However, over the last year or so I have taken quite a shine to Microsoft’s new FP language (F#), not just because purely functional program code is concise powerful and elegant, but because the eclectic mix of functional and OOP paradigms in F# enable me to develop better, faster, stronger and more maintainable applications.

In investment banking, the business has been changing fast, and being able to get production quality WPF apps onto the trader desks has been a big priority, and with F# I find myself more able to meet that challenge.

The WPF design pattern ‘du jour’ is MVVM. Anyone who’s serious about enterprise-strength development in WPF would have come across this pattern and probably have used it at some point in the recent past.

Detailed below is a very basic implementation where :-

  1. There is a WPF project that contains only Views
  2. There is a C# ‘model’ project that contains only the generated classes from SqlMetal (for Linq to SQL)
  3. The is an F# code library project that contains my ViewModel

The F# ViewModel is a very simple one, but it covers all the main bases:-

  1. It has a generic ICommand implementation for command binding
  2. It implements INotifyPropertyChanged for change notifications
  3. It has Data for binding

So here it is

#light
module FSharpMVVM
 
open System
open System.Windows.Input
open System.Data.SqlClient
open System.ComponentModel
open FsMVVM.DAL
 
// below is our Linq-SQL data context, created via SqlMetal and in a separate
// C# project - as SqlMetal doesnt generate F# yet *)
 
let ctx = new DataClassesDataContext()
 
// an implemnentation of a generic ICommand, that takes two functions
// one to see if the command can be executed, and one to execute the command 
 
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)
 
// Our ViewModel is below
 
type MainViewModel() =  
    let mutable prods = Seq.toList ctx.Products 
    let a =  new PropertyChangedEventArgs("ProductData")
    let propChangedEvent = new DelegateEvent<PropertyChangedEventHandler>()
    interface INotifyPropertyChanged with 
        [<CLIEvent>]
        member x.PropertyChanged = propChangedEvent.Publish
    member x.ProductData with get() = prods
    member x.FilterCommand = 
        new FuncCommand(
            (fun d -> not(Seq.isEmpty ctx.Products)),
            (fun e -> prods <- Seq.toList ctx.Products 
                    |> List.filter (
                        fun p -> p.ProductName.Contains(e.ToString()));
                        propChangedEvent.Trigger([| box x; box a|])))

 

and below is the simple View (XAML)

 

<Window x:Class="FsMVVM.WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Margin="5">
            <TextBox Name="searchText" MinWidth="100" />
            <Button Content="Search" Command="{Binding FilterCommand}" 
                    CommandParameter="{Binding ElementName=searchText, Path=Text}" />
        </StackPanel>
        <ListView ItemsSource="{Binding ProductData}" Grid.Row="1">
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="Name" DisplayMemberBinding="{Binding ProductName}" />
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

 

and finally, its wired up in the code-behind

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new FSharpMVVM.MainViewModel();
    }
}

and that's all it takes

Now, I know that there isnt a great deal of functional programming in this example, but now I have the building blocks for a more complex ViewModel, that will no doubt include a great deal more FP before it is finished

 

Dean

Tags: ,

DataBinding | F# | MVVM

Comments


April 13. 2010 07:52
trackback
F# And MVVM - A Simple ViewModel

You've been kicked (a good thing) - Trackback from DotNetKicks.com


April 14. 2010 18:42
pingback
Pingback from topsy.com

Twitter Trackbacks for
        
        Dean Chalk's Blog | F# And MVVM – A Simple ViewModel
        [deanchalk.me.uk]
        on Topsy.com


April 20. 2010 11:55
trackback
Social comments and analytics for this post

This post was mentioned on Twitter by corcav: MVVM in F# Smile http://bit.ly/9r05IO

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading

FAO Comment Spammers : Please note that this blog is fully moderated by me personally and no comment spam will ever appear on this site.



RecentComments

Comment RSS
Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2012 Dean Chalk's Blog