Is it possible to implement INotifyPropertyChanged as a type extension in F #
In C #, you can implement a PropertyChangedEventHandler based extension method like this:
static class VMExts
{
public static void RaisePropertyChanged(this PropertyChangedEventHandler handler, object sender, string propName)
{
if(handler != null)
{
handler(sender, new PropertyChangedEventArgs(propName));
}
}
}
What can be called the following:
class VM : INotifyPropertyChanged
{
private string _someText;
public event PropertyChangedEventHandler PropertyChanged;
public string SomeText
{
get { return _someText; }
set
{
_someText = value;
PropertyChanged.RaisePropertyChanged(this, "SomeText");
}
}
}
I'm trying to achieve something similar in F #, but can't figure out the syntax. Obviously it is quite easy to achieve this by inheriting from some ViewModelBase style class such as http://www.fssnip.net/2x , but it would be nice to have an extension method.
So, given this class:
type ViewModelBase() = let mutable _someText = "" let propertyChanged = Event<_, _>() interface INotifyPropertyChanged with [<CLIEvent>] member x.PropertyChanged = propertyChanged.Publish member x.SomeText with get() = _someText and set(value) = _someText <- value (x :> INotifyPropertyChanged).PropertyChanged.RaisePropertyChanged("SomeText")
I tried:
type PropertyChangedEventHandler with member x.RaisePropertyChanged(sender, propName) = if x <> null then x.Invoke(sender, PropertyChangedEventArgs(propName))
and
open System.Runtime.CompilerServices [<Extension>] type VmExtensions() = [<Extension>] static member inline RaisePropertyChanged(handler : PropertyChangedEventHandler, propName) = if handler <> null then handler.Invoke(handler, PropertyChangedEventArgs(propName))
I think they cannot be found as valid for PropertyChanged because PropertyChanged type is IEvent whereas I extended PropertyChangedEventHandler type.
So I tried:
type IEvent<PropertyChangedEventHandler, PropertyChangedEventArgs> with member x.RaisePropertyChanged(sender, propName) = if x <> null then x.Invoke(sender, PropertyChangedEventArgs(propName))
But the compiler doesn't like using IEvent
[<Extension>] type VmExtensions() = [<Extension>] static member inline RaisePropertyChanged(handler : IEvent<PropertyChangedEventHandler, PropertyChangedEventArgs>, propName) = // if handler <> null then handler.Invoke(handler, PropertyChangedEventArgs(propName))
But IEvent only has a Subscribe method
thank
source to share
You can raise the event with a method Trigger
that is defined in Event
(not on IEvent
):
[<Extension>]
type VmExtensions =
[<Extension>]
static member inline RaisePropertyChanged
(ev:Event<PropertyChangedEventHandler, _>, propName) =
ev.Trigger(null, PropertyChangedEventArgs propName)
source to share