实现属性变化自动通知的最简单方法

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 设备发送推送通知的最简单方法是啥?

在颤动中显示通知的最简单方法?

使用 NodeJS 向 iOS 应用程序发送推送通知的最简单方法是啥?

传递信息并从另一个线程通知一个线程的最简单方法

kvo

使用 CSHTML 进行自动完成的最简单方法是啥