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,
Also, added this in the F# snippets site here.
Hope this helps.
-Fahad