实现属性更改自动通知的最简单方法

发布于 2024-10-12 18:03:20 字数 745 浏览 6 评论 0原文

我知道有一些解决方案可以实现 INotifyPropertyChanged,但没有一个那么简单:引用这个库,创建/添加这个属性,完成(我在这里考虑面向方面的编程)。有谁知道一个非常简单的方法来做到这一点?如果解决方案是免费的,则可获得奖励积分。

以下是一些相关链接(没有一个提供足够简单的答案):

I know that there are solutions out there for implementing INotifyPropertyChanged, but none of them are as simple as: reference this library, create/add this attribute, done (I'm thinking Aspect-Oriented Programming here). Does anyone know of a really simple way to do this? Bonus points if the solution is free.

Here are some relevant links (none of which provide a simple enough answer):

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

迎风吟唱 2024-10-19 18:03:20

试试这个
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));    
        }
    }
}

或者您可以使用属性进行更细粒度的控制。

Try this
https://github.com/Fody/PropertyChanged

It will weave all properties of types that implement INotifyPropertyChanged and even handles dependencies.

Your Code

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);
        }
    }

}

What gets compiled

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));    
        }
    }
}

Or you can use attributes for more fine grained control.

埖埖迣鎅 2024-10-19 18:03:20

这是一篇文章,展示了如何通过 PostSharp 处理此问题

Here is an article showing how to handle this via PostSharp.

白昼 2024-10-19 18:03:20

西蒙的答案就是解决方案,但这是我的代码和屏幕截图供参考。我正在使用 Prism(使用 MEF - 忽略类上的属性),因此我从 INotifyPropertyChanged 的​​ NotificationObject 继承。 (它定义了一个 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>

反射器代码

编织了 INPC 后的代码。

Simon's answer is the solution, but here's my code and a screenshot for reference. I am using Prism (with MEF - ignore the attributes on the class), so I inherit from NotificationObject for INotifyPropertyChanged. (It defines a RaisePropertyChanged method, so you have to tell NotifyPropertyWeaver that in your project file.)

The Class

using System.ComponentModel.Composition;
using Microsoft.Practices.Prism.ViewModel;

[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class SignControllerViewModel : NotificationObject
{
    public string Uri { get; set; }
}

The Project File

<?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>

The Reflector Code

Code after INPC has been weaved into it.

扬花落满肩 2024-10-19 18:03:20

还有UpdateControls.NET。我没有使用过它,它看起来比notifypropertyweaver需要更多工作,但它可能很好。来自网站:

没有 INotifyPropertyChanged 的​​数据绑定

更新控件不需要您实现 INotifyPropertyChanged 或声明 DependencyProperty。它将控件直接连接到 CLR 属性。它通过中间代码层发现对数据的依赖关系。这使得它非常适合模型/视图/视图模型模式; ViewModel 中不需要额外的代码,它位于模型和视图之间。

包装窗口的 DataContext。包装器不仅为所有对象的属性实现 INotifyPropertyChanged,还自动检测它们对其他属性的依赖关系。没有要实现的基类或接口。

There is also UpdateControls.NET. I haven't used it, and it looks like more work than notifypropertyweaver, but it might be good. From the website:

Data binding without INotifyPropertyChanged

Update Controls does not require that you implement INotifyPropertyChanged or declare a DependencyProperty. It connects controls directly to CLR properties. It discovers dependencies upon data through layers of intermediate code. This makes it perfect for the Model/View/ViewModel pattern; no extra code is needed in the ViewModel, which sits between the Model and the View.

Wrap the DataContext of your Window. The wrapper not only implements INotifyPropertyChanged for all of your object's properties, it also automatically detects their dependencies on other properties. There is no base class or interface to implement.

初见终念 2024-10-19 18:03:20

有一个名为 Polymod 的项目。其中提供了您正在寻找的东西。它确实有一些很酷的功能,例如定义自动更新公式。例如,如果 Sum = A + B,则当 A 或 B 更改时,PropertyChanged 将在 Sum 上调用。

它还可以与开箱即用的规则引擎配合使用,为您提供验证。
因为它是可扩展的,所以也可以使用其他验证框架。

面向方面的编程处于最佳状态!

There is a project called Polymod. Which offers what you are looking for. It does have some some cool features such as defining self-updating formulas. E.g. If Sum = A + B, then PropertyChanged is called on Sum when A or B is changed.

It also works with Rules Engine out-of-the-box to give you validation as well.
Because it is extensible, it is possible to use other Validation Frameworks as well.

Aspect-Orientated programming at its best!

我不会写诗 2024-10-19 18:03:20

还有 KindOfMagic,使用起来非常简单。只需创建一个“Magic”属性并应用它即可。 https://www.nuget.org/packages/KindOfMagic

There is also KindOfMagic which is very simple to use. Just create a "Magic" attribute and apply it. https://www.nuget.org/packages/KindOfMagic

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文