Mvvm 是否可以在F中将INotifyPropertyChanged实现为类型扩展#
在C#中,您可以实现基于PropertyChangedEventHandler的扩展方法,如下所示:Mvvm 是否可以在F中将INotifyPropertyChanged实现为类型扩展#,mvvm,f#,extension-methods,inotifypropertychanged,Mvvm,F#,Extension Methods,Inotifypropertychanged,在C#中,您可以实现基于PropertyChangedEventHandler的扩展方法,如下所示: static class VMExts { public static void RaisePropertyChanged(this PropertyChangedEventHandler handler, object sender, string propName) { if(handler != null) { handler
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");
}
}
}
可称之为:
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样式的类(如)很容易实现这一点,但是如果有一个扩展方法就更好了
因此,考虑到这一类:
键入ViewModelBase()=
让可变的_someText=“”
让propertyChanged=事件()
接口INotifyProperty更改为
[]
成员x.PropertyChanged=PropertyChanged.Publish
成员x.SomeText
使用get()=\u someText
和设置(值)=
_someText INotifyPropertyChanged).PropertyChanged.RaisePropertyChanged(“someText”)
我试过:
使用
成员x.RaisePropertyChanged(发送方,propName)=
如果x为空,则
x、 调用(发送方,PropertyChangedEventArgs(propName))
及
open System.Runtime.CompilerServices
[]
类型VmExtensions()=
[]
静态成员内联RaisePropertyChanged(处理程序:PropertyChangedEventHandler,propName)=
如果处理程序为null,则
调用(handler,PropertyChangedEventArgs(propName))
我认为这些属性对于PropertyChanged是无效的,因为PropertyChanged的类型是IEEvent,而我扩展了PropertyChangedEventHandler类型
因此,我尝试:
使用
成员x.RaisePropertyChanged(发送方,propName)=
如果x为空,则
x、 调用(发送方,PropertyChangedEventArgs(propName))
但是编译器不喜欢IEvent的用法
[]
类型VmExtensions()=
[]
静态成员内联RaisePropertyChanged(处理程序:IEvent,propName)=
//如果处理程序为null,则
调用(handler,PropertyChangedEventArgs(propName))
但是IEvent实际上只有一个Subscribe方法
谢谢您可以通过
触发器
方法引发事件,该方法在事件
上定义(而不是在事件
上定义):
[]
类型VmExtensions=
[]
静态成员内联RaisePropertyChanged
(ev:事件、名称)=
ev.Trigger(null,PropertyChangedEventArgs propName)
啊,是的,很有效,谢谢。很遗憾,我需要强制转换在PropertyChanged.Publish中创建的IEvent。我需要在RaisePropertyChanged函数中执行此操作,并在强制转换失败时引发异常,或者,在我使用INotifyPropertyChanged的任何地方都执行此操作。很高兴您找到了有效的方法。那你能核对一下答案吗。另一方面,我真的不明白你为什么要使用一种方法,首先需要从IEvent<,>
到Event<,>
进行转换。避免重复执行INotifyPropertyChanged
的通常解决方案是简单地从ViewModelBase
类继承,该类定义了某种(内部)OnNotivyPropertyChanged
方法,继承者可以调用该方法。这不是“惯用的功能性”F#,但从语用的角度来看,它完全可以。是的,你是对的。我忘了我已经创建了这个活动,并且可以访问它,所以我关于演员的观点是无关紧要的。利用这一点,我提出了一些我非常喜欢的实现。