实现属性变化自动通知的最简单方法
Posted
技术标签:
【中文标题】实现属性变化自动通知的最简单方法【英文标题】:Simplest way to achieve automatic notification of property change 【发布时间】:2011-06-10 15:00:48 【问题描述】:我知道那里有实现 INotifyPropertyChanged 的解决方案,但没有一个像这样简单:引用这个库,创建/添加这个属性,完成(我在这里考虑面向方面的编程)。有谁知道一个非常简单的方法来做到这一点?如果解决方案是免费的,则奖励积分。
以下是一些相关链接(没有一个提供足够简单的答案):
Aspect Examples (INotifyPropertyChanged via aspects) LinFu INotifyPropertyChanged auto wiring or how to get rid of redundant code INotifyPropertyChanged With Unity Interception AOP【问题讨论】:
【参考方案1】:试试这个 https://github.com/Fody/PropertyChanged
它将编织实现 INotifyPropertyChanged 甚至处理依赖关系的类型的所有属性。
你的代码
public class Person : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public string GivenNames get; set;
public string FamilyName get; set;
public string FullName
get
return string.Format("0 1", GivenNames, FamilyName);
编译的内容
public class Person : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private string givenNames;
public string GivenNames
get return givenNames;
set
if (value != givenNames)
givenNames = value;
OnPropertyChanged("GivenNames");
OnPropertyChanged("FullName");
private string familyName;
public string FamilyName
get return familyName;
set
if (value != familyName)
familyName = value;
OnPropertyChanged("FamilyName");
OnPropertyChanged("FullName");
public string FullName
get
return string.Format("0 1", GivenNames, FamilyName);
public void OnPropertyChanged(string propertyName)
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
或者您可以使用属性进行更细粒度的控制。
【讨论】:
NotifyPropertyWeaver was deprecated。作者建议移到Fody+PropertyChanged Fody 的功能是有限的,它只处理类本身的依赖关系,并且不传播依赖于某些嵌套视图模型的属性的属性。这是 PostSharp 可以提供的。【参考方案2】:这是一篇显示how to handle this via PostSharp的文章。
【讨论】:
谢谢里德。我添加了一条说明,说明理想的解决方案将比 200 美元便宜得多(对于 PostSharp)。我知道有一个免费的 PS 版本,但我无法通过那个版本实现我的目标。【参考方案3】:Simon's answer 是解决方案,但这是我的代码和截图供参考。我正在使用 Prism(使用 MEF - 忽略类上的属性),所以我从 NotificationObject 继承 INotifyPropertyChanged。 (它定义了一个RaisePropertyChanged
方法,所以你必须在你的项目文件中告诉NotifyPropertyWeaver。)
类
using System.ComponentModel.Composition;
using Microsoft.Practices.Prism.ViewModel;
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class SignControllerViewModel : NotificationObject
public string Uri get; set;
项目文件
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- snipped -->
<UsingTask TaskName="NotifyPropertyWeaverMsBuildTask.WeavingTask" AssemblyFile="$(SolutionDir)lib\NotifyPropertyWeaverMsBuildTask.dll" />
<Target Name="AfterBuild">
<NotifyPropertyWeaverMsBuildTask.WeavingTask
TargetPath="$(TargetPath)"
TryToWeaveAllTypes="true"
EventInvokerName="RaisePropertyChanged"
MessageImportance="High"/>
</Target>
</Project>
反射器代码
【讨论】:
我将很快创建一个新的 wiki 页面,其中显示 Prism、Caliburn、Caliburn Micro 和 MVVMLight 的推荐设置 我建议不要使用 NotificationObject。它给你的只是 RaisePropertyChanged 方法。如果您只是在模型中实现 INotifyPropertyChanged,NotifyPropertyWeaver 将为您注入该方法。【参考方案4】:还有UpdateControls.NET。我没用过,它看起来比 notifypropertyweaver 工作更多,但它可能会很好。来自网站:
没有 INotifyPropertyChanged 的数据绑定
Update Controls 不需要您实现 INotifyPropertyChanged 或声明 DependencyProperty。它将控件直接连接到 CLR 属性。它通过中间代码层发现对数据的依赖关系。这使得它非常适合 Model/View/ViewModel 模式; ViewModel 中不需要额外的代码,它位于 Model 和 View 之间。
包装窗口的 DataContext。包装器不仅为对象的所有属性实现 INotifyPropertyChanged,它还自动检测它们对其他属性的依赖关系。没有要实现的基类或接口。
【讨论】:
感谢您的提及。 Update Controls 是一个依赖跟踪库。但它不是 INotifyPropertyChanged 的直接实现。是的,它比 Notify Property Weaver 工作更多。所以这不是你在问题中要求的。【参考方案5】:有一个名为Polymod 的项目。它提供了您正在寻找的东西。它确实有一些很酷的功能,例如定义自更新公式。例如。如果 Sum = A + B,则当 A 或 B 发生更改时,将对 Sum 调用 PropertyChanged。
它还可以与开箱即用的Rules Engine 一起使用,以便为您提供验证。 因为它是可扩展的,所以也可以使用其他验证框架。
面向方面的编程处于最佳状态!
【讨论】:
【参考方案6】:还有 KindOfMagic,使用起来非常简单。只需创建一个“魔法”属性并应用它。 https://www.nuget.org/packages/KindOfMagic
【讨论】:
以上是关于实现属性变化自动通知的最简单方法的主要内容,如果未能解决你的问题,请参考以下文章
与 APNS 服务器交互以向 iOS 设备发送推送通知的最简单方法是啥?