F# Quotations for INotifyPropertyChanged

I was wanting to use F# quotations with INotifyPropertyChanged for quite sometime now, Since I’m working on pure usage of F# in WPF and Silverlight this is one part that would help using F# with Visual Studio. There are lots of ViewModelBase implementation in C# that utilizes the LINQ expressions when you want to declare CLR properties. The LINQ Expression<Func> allows you to write strongly typed code in C# for defining the property,

private object selectedItem = null
public object SelectedItem
{
	get{ return this.selectedItem; }
	set
	{
		if(this.selectedItem != value)
		{
			this.selectedItem = value;
			this.OnPropertyChanged(() => this.SelectedItem)
		}
	}
}

The above code uses a strongly-typed OnPropertyChanged method that in-turn parses out the property name and passes that to the INotifyPropertyChanged interface.

Now that I’m officially working on full-time F# work, I was happy to get this done. Below code shows the ViewModelBase implementation utilizing the F# quotations,

open System
open System.Collections.ObjectModel
open System.ComponentModel
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns

type ViewModelBase() =
    let propertyChanged = new Event<_, _>()
    let toPropName(query : Expr) = 
        match query with
        | PropertyGet(a, b, list) ->
            b.Name
        | _ -> ""

    interface INotifyPropertyChanged with
        [<CLIEvent>]
        member x.PropertyChanged = propertyChanged.Publish

    abstract member OnPropertyChanged: string -> unit
    default x.OnPropertyChanged(propertyName : string) =
        propertyChanged.Trigger(x, new PropertyChangedEventArgs(propertyName))

    member x.OnPropertyChanged(expr : Expr) =
        let propName = toPropName(expr)
        x.OnPropertyChanged(propName)

To use the above, You need to inherit the ViewModelBase to your custom type and then call the OnPropertyChanged method with the F# quotations. Below is an example showing how to declare the same “SelectedItem” property in F#,

    let mutable selectedItem : obj = null

    member x.SelectedItem
        with get() = selectedItem
        and set(v : obj) = 
            selectedItem <- v
            x.OnPropertyChanged(<@ x.SelectedItem @>)

The F# quotations are wrapped around <@@> block, this is the syntax in F#. Now you get full intelli-sense with Visual Studio too,

image

Also, added this in the F# snippets site here.

Hope this helps.

-Fahad

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: