INotifyPropertyChanged和自动属性

时间:2010-07-27 19:42:07

标签: c# .net vb.net

有没有办法将INotifyPropertyChanged与自动属性一起使用?也许是一个属性或其他东西,对我来说并不明显。

public string Demo{
    get;set;
}

对我来说,自动属性是一个非常实用的东西,但几乎总是,如果属性值已经更改并且没有执行此操作的机制,我必须引发PropertyChanged - 事件,自动属性对我来说没用。

6 个答案:

答案 0 :(得分:12)

在.NET 4.5和higher it can be made somewhat shorter中:

private int unitsInStock;
public int UnitsInStock
{
    get { return unitsInStock; }
    set { SetProperty(ref unitsInStock, value);}
}

答案 1 :(得分:11)

这是你必须自己编码的东西。您可以获得的最接近的类似于Code Project上的this implementation,它使用自定义属性和面向方面的方法来提供此语法:

[NotifyPropertyChanged] 
public class AutoWiredSource
{ 
   public double MyProperty { get; set; } 
}

有人曾经在Microsoft Connect上提出过对C#规范的更改实现这个:

class Person : INotifyPropertyChanged
{
    // "notify" is a context keyword, same as "get" and "set"
    public string Name { get; set; notify; }
}

proposal现已关闭。

答案 2 :(得分:9)

没有内置机制来执行此操作。像PostSharp这样的东西可能会为你添加这样的东西(或Mark Gravell的HyperDescriptor,如果你只是想让这个数据绑定感知的话。)

答案 3 :(得分:2)

INotifyPropertyChanged和DependencyProperties确实使属性变得不那么有趣。我发现的最好的解决方案是好的片段。比如Silverlight contrib项目中的那些

答案 4 :(得分:1)

我首先尝试使用其他方法:

这些方法有效,但是我仍然不得不混淆模型中所有属性的访问器方法,或使用dynamic对象在编码时杀死自动完成。值得一提的是,不幸的是,WinForms不支持绑定到动态对象。

解决方案

最终我遇到了ReactiveUI.Fody。它是一个使用Fody和ReactiveUI的简单易用的解决方案。我成功地在我的WPF项目中使用了它。

它在编译时编织所需的样板代码RaisePropertyChangesObservableAsPropertyHelper

项目依赖项

https://github.com/kswoll/ReactiveUI.Fody

我使用NuGet在我的项目中安装了以下软件包:

<packages>
  <package id="Fody" version="2.0.7" targetFramework="net452" developmentDependency="true" />
  <package id="reactiveui" version="7.4.0" targetFramework="net452" />
  <package id="ReactiveUI.Fody" version="2.2.11" targetFramework="net452" />
  <package id="reactiveui-core" version="7.4.0" targetFramework="net452" />
  <package id="Rx-Core" version="2.2.5" targetFramework="net452" />
  <package id="Rx-Interfaces" version="2.2.5" targetFramework="net452" />
  <package id="Rx-Linq" version="2.2.5" targetFramework="net452" />
  <package id="Rx-Main" version="2.2.5" targetFramework="net452" />
  <package id="Rx-PlatformServices" version="2.2.5" targetFramework="net452" />
  <package id="Rx-XAML" version="2.2.5" targetFramework="net452" />
  <package id="Splat" version="1.6.0" targetFramework="net452" />
</packages>

Fody Setup

您需要在项目的顶层创建一个FodyWeavers.xml文件,如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
  <ReactiveUI/>
</Weavers>

用法

您只需将Model类设置为继承ReactiveObject并添加 您想要通知更改的任何属性上方的[Reactive]属性。

using ReactiveUI;
using ReactiveUI.Fody.Helpers;

namespace name.domain.some{
    class SomeClass : ReactiveObject {
        [Reactive]
        public string SomeProperty { get; set; }
    }
}

完成工作!重建项目并检查Visual Studio中的输出窗口。您应该看到Fody输出的一些行,因为它处理带注释的Model类并注入适当的样板代码。看起来应该是这样的:

enter image description here

更多信息

可以找到更多有用的信息here

答案 5 :(得分:0)

Useful answer

crea7or,最终在我的最新项目中使用了它。改善它的一种方法是通过以下方式重写SetProperty:

protected bool SetProperty<T>(ref T storage, T value, string[] dependentPropertyNames = null, [CallerMemberName] string propertyName = null)
{
    if (Equals(storage, value))
    {
        return false;
    }

    storage = value;
    this.OnPropertyChanged(propertyName);

    if(dependentPropertyNames != null)
    {
        foreach(var dependentPropertyName in dependentPropertyNames)
        {
            OnPropertyChanged(dependentPropertyName);
        }
    }

    return true;
}

现在,它允许传入相关属性名称,以使视图知道相关属性值已更改,即使该属性值不是直接设置的,而是由于设置了其他属性。

用法:

private string firstName;
public string FirstName
{
    get { return firstName; }
    set { SetProperty(ref firstName, value, new[] { "FullName" }); }
}

private string lastName;
public string LastName
{
    get { return lastName; }
    set { SetProperty(ref lastName, value, new[] { "FullName" }); }
}

public string FullName
{
    get { return $"{FirstName} {LastName}"; }
}