Yes the correct way seems to be to override the add and remove methods. Belows an implemntation of binding list that compiles, but obviously isn't correct. To invoke then event you need to iterate though the handlers collection and invoke each event handler that you find, obviously not ideal, there maybe a better way to do this. I think this is because interfaces that contain event are relatively rare, and have probably been a bit overlooked. I would _guess_ this is one area that maybe improved in the future.
Also not that it is alot easier to expose an event from a class. All you need to do is expose the a value create via IEvent.create_HandlerEvent, yes there is some compiler magic to make events first class values in F#. More details here: http://blogs.msdn.com/dsyme/archive/2006/03/24/559582.aspx
open System.ComponentModel
type BindingList() = class
let handlers = new ResizeArray<ListChangedEventHandler>()
interface IBindingList with
member x.remove_ListChanged(eh : ListChangedEventHandler) = handlers.Remove(eh) |> ignore
member x.add_ListChanged(eh : ListChangedEventHandler) = handlers.Add(eh)
member x.AddIndex(prop : PropertyDescriptor) = ()
member x.AddNew() = (null :obj)
member x.ApplySort(prop : PropertyDescriptor, direction : ListSortDirection) = ()
member x.Find(prop : PropertyDescriptor, key : obj ) = 0
member x.RemoveIndex(prop : PropertyDescriptor ) = ()
member x.RemoveSort() = ()
member x.AllowEdit
with get() = true
member x.AllowNew
with get() = true
member x.AllowRemove
with get() = true
member x.IsSorted
with get() = true
member x.SortDirection
with get() = ListSortDirection.Ascending
member x. SortProperty
with get() = (null: PropertyDescriptor)
member x.SupportsChangeNotification
with get() = true
member x.SupportsSearching
with get() = true
member x.SupportsSorting
with get() = true
member x.Add(value:obj) = 0;
member x.Clear() = ()
member x.Contains(value:obj) = true
member x.IndexOf(value:obj) = 0
member x.Insert(index : int , value: obj) =()
member x.Remove(value : obj) = ()
member x.RemoveAt(index : int) = ()
member x.IsFixedSize
with get() = true
member x.IsReadOnly
with get() = true
member x.Item
with get(i : int) = null
and set (i: int) (o : obj) =()
member x.CopyTo(array : System.Array, index : int ) =()
member x.Count
with get() = 0
member x.IsSynchronized
with get() = true
member x.SyncRoot
with get() = new obj()
member x.GetEnumerator() = (null: System.Collections.IEnumerator)
end
end
Robert Pickering, MVP
http://strangelights.com