在C#中,您可以实现基于PropertyChangedEventHandler的扩展方法,如下所示:
static class VMExts
{
public static void RaisePropertyChanged(this PropertyChangedEventHandler handler, object sender, string propName)
{
if(handler != null)
{
handler(sender, new PropertyChangedEventArgs(propName));
}
}
}
可以如下调用:
class VM : INotifyPropertyChanged
{
private string _someText;
public event PropertyChangedEventHandler PropertyChanged;
public string SomeText
{
get { return _someText; }
set
{
_someText = value;
PropertyChanged.RaisePropertyChanged(this, "SomeText");
}
}
}
我一直试图在F#中实现类似的功能,但无法弄清楚语法。 通过继承一些ViewModelBase样式类(例如http://www.fssnip.net/2x)来实现这一点显然很容易,但是使用扩展方法真的很不错。
所以,鉴于这个课程:
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")
我试过了:
type PropertyChangedEventHandler with
member x.RaisePropertyChanged(sender, propName) =
if x <> null then
x.Invoke(sender, PropertyChangedEventArgs(propName))
和
open System.Runtime.CompilerServices
[<Extension>]
type VmExtensions() =
[<Extension>]
static member inline RaisePropertyChanged(handler : PropertyChangedEventHandler, propName) =
if handler <> null then
handler.Invoke(handler, PropertyChangedEventArgs(propName))
我认为找不到这些对PropertyChanged有效,因为PropertyChanged的类型是IEvent,而我扩展了PropertyChangedEventHandler类型。
然后我尝试了:
type IEvent<PropertyChangedEventHandler, PropertyChangedEventArgs> with
member x.RaisePropertyChanged(sender, propName) =
if x <> null then
x.Invoke(sender, PropertyChangedEventArgs(propName))
但编译器并不喜欢IEvent的用法
[<Extension>]
type VmExtensions() =
[<Extension>]
static member inline RaisePropertyChanged(handler : IEvent<PropertyChangedEventHandler, PropertyChangedEventArgs>, propName) =
// if handler <> null then
handler.Invoke(handler, PropertyChangedEventArgs(propName))
但IEvent确实只有一个Subscribe方法
由于
答案 0 :(得分:4)
您可以通过Trigger
方法(Event
上未定义的IEvent
方法提出事件:
[<Extension>]
type VmExtensions =
[<Extension>]
static member inline RaisePropertyChanged
(ev:Event<PropertyChangedEventHandler, _>, propName) =
ev.Trigger(null, PropertyChangedEventArgs propName)