有没有办法自动获得类中属性更改的通知,而无需在每个setter中编写OnPropertyChanged? (如果有更改,我有数百个我想知道的属性) .
安东建议dynamic proxies . 我必须写,它在我的程序启动时间(ymmv)增加了大约30秒 - 因为它是一个运行时解决方案 .
我想知道是否有编译时解决方案,可能使用编译时属性...
Slashene和TcKs给出了产生重复代码的建议 - 遗憾的是,并非所有属性都是m_Value = value的简单情况 - 很多都在setter中有自定义代码,所以来自代码片段和xml的cookie-cutter代码实际上不可行我的项目也是 .
13 回答
EDIT: NotifyPropertyWeaver的作者已弃用该工具,转而采用更为通用的Fody . (对于从织布 Worker 到战士的人,可以使用migration guide . )
我用于项目的一个非常方便的工具是Notify Property Weaver Fody .
它将自身安装为项目中的构建步骤,并在编译期间注入引发
PropertyChanged
事件的代码 .使属性提升PropertyChanged是通过将special attributes放在它们上来完成的:
作为奖励,您还可以指定依赖于其他属性的属性的关系
nameof运算符是在2015年7月使用.NET 4.6和VS2015在C#6.0中实现的 . 以下内容对C#<6.0仍然有效
我们使用下面的代码(来自http://www.ingebrigtsen.info/post/2008/12/11/INotifyPropertyChanged-revisited.aspx) . 很棒:)
例如这样使用:
示例中可能存在一些语法错误 . 没试过 . 但你应该至少有这个概念:)
EDIT: 我现在看到你可能想要更少的工作,但是......上面的东西至少使它变得容易多了 . 并且使用字符串引用属性可以防止所有可怕的问题 .
Framework 4.5为我们提供了CallerMemberNameAttribute,这使得将属性名称作为字符串传递是不必要的:
类似于Svish的解决方案,只需用无聊的框架功能取代lambda awesomeness ;-)
如果您正在使用安装了KB2468871的Framework 4.0,则可以通过nuget安装Microsoft BCL兼容包,它也提供此属性 .
您可以在PropertyChanged委托上使用扩展方法并像这样使用它:
订阅特定房产变更:
扩展方法只能通过检查lambda表达式树来确定发送方和属性名称,而不会对性能产生重大影响:
如果
PropertyChanged
事件在基类型中声明,则它将不会在派生类中作为委托字段显示 . 在这种情况下,解决方法是声明PropertyChangedEventHandler
类型的受保护字段并显式实现事件的add
和remove
访问者:实现类型安全
INotifyPropertyChanged
:See here然后制作自己的代码段:
随着Code snippet designer而你已经完成了!简单,安全的方式来 Build 您的INotifyPropertyChanged .
我不知道没有标准的方法,但我知道两个解决方法:
1)PostSharp可以在编译后为你做 . 它非常有用,但每次构建都需要一些时间 .
2)自定义工具i Visual Studio . 您可以将其与“部分类”结合使用 . 然后,您可以为XML创建自定义工具,并且可以从xml生成源代码 .
例如这个xml:
可以是此代码的来源:
您可能希望从整体上考虑面向方面编程
框架=>你可以看linfu
您可以查看Castle或Spring.NET并实现拦截器功能吗?
改进儿童课程中的活动:
感谢:this.NotifyPropertyChange(()=> PageIndex);
在NotificationExtensions类中添加:
我刚刚发现ActiveSharp - Automatic INotifyPropertyChanged,我还没有使用它,但它看起来不错 .
引用它的网站......
相反,写这样的属性:
请注意,不需要将属性的名称包含在字符串中 . ActiveSharp可靠而正确地为自己确定了这一点 . 它的工作原理是您的属性实现通过了支持字段(_foo)由ref . (ActiveSharp使用“by ref”调用来标识传递了哪个支持字段,并从字段中识别属性) .
只是为了实现 quicker ,你可以使用一个片段
从http://aaron-hoffman.blogspot.it/2010/09/visual-studio-code-snippet-for-notify.html
片段核心( full credit 给作者,不是我的)是以下内容
Property Changed没有Single实现可以处理人们想要使用它的各种方式 . 最好的办法是生成一个帮助类来为你做这项工作,这是我使用的一个例子
编辑:有人建议我从一个助手类转移到一个值包装器,我已经使用这个,我发现它工作得很好
使用的例子
然后在构造函数中你做
只需在自动属性声明上方使用此 attribute 即可