I like F# for a lot of things, but, man, is it a pain to support events. In C# it’s trivial to implement an interface like INotifyPropertyChanged consisting only of an event, but in F# you have to jump through some hoops to map native functions to delegates/events. F# is generally much terser than C# and other .NET languages, but not in this case. After spending some time the other day trying to figure out the right combination of syntax and helper functions (and unsucessfully googling for it), I thought I’d upload a bare-bones implementation here as an aide-memoire.
open System.ComponentModel type MyObject() = let mutable propval = 0.0 let event = Event<_, _>() interface INotifyPropertyChanged with member this.add_PropertyChanged(e) = event.Publish.AddHandler(e) member this.remove_PropertyChanged(e) = event.Publish.RemoveHandler(e) member this.MyProperty with get() = propval and set(v) = propval <- v event.Trigger(this, new PropertyChangedEventArgs("MyProperty"))
It turns out that in F# version 1.9.6.16 there’s a slightly more concise syntax for this, as pointed out by Rei in the comments (thanks!). It uses the CLIEvent attribute to hook up the .NET event:
open System.ComponentModel type MyObject() = let mutable propval = 0.0 let propertyChanged = Event<_, _>() interface INotifyPropertyChanged with [<clievent>] member x.PropertyChanged = propertyChanged.Publish member this.MyProperty with get() = propval and set(v) = propval <- v propertyChanged.Trigger(this, new PropertyChangedEventArgs("MyProperty"))

4 Comments
Thanks. I was looking at this problem last night, and didn’t find much documentation to guide me.
Here’s a much easier way to do it:
let propertyChanged = Event()
interface INotifyPropertyChanged with
[]
member x.PropertyChanged = propertyChanged.Publish
member private x.propchg p = propertyChanged.Trigger(x, PropertyChangedEventArgs(p))
Blah, lost the brackets to html. Let’s try again:
let propertyChanged = Event<_, _>()
interface INotifyPropertyChanged with
[<CLIEvent>]
member x.PropertyChanged = propertyChanged.Publish
member private x.propchg p = propertyChanged.Trigger(x, PropertyChangedEventArgs(p))
Thanks Rei! I’ve updated the post to mention the new attribute (and change the code to use type inference for the event type).
Ian