C# 在类中使用INotifyPropertyChanged

C# 在类中使用INotifyPropertyChanged,c#,wpf,C#,Wpf,C#允许创建如下属性: public string SomeRandomText { get; set; } 框架处理此属性的支持变量的创建。我如何拥有这样一个属性,并且仍然有更改通知 在实现INotifyPropertyChanged的类中允许这样做吗 public string SomeRandomTextBeingNotified { get; set { NotifyPropertyChanged("SomeRandomTextBeing

C#允许创建如下属性:

public string SomeRandomText
{
    get; set;
}
框架处理此属性的支持变量的创建。我如何拥有这样一个属性,并且仍然有更改通知

在实现INotifyPropertyChanged的类中允许这样做吗

public string SomeRandomTextBeingNotified
{
    get;
    set
    {
        NotifyPropertyChanged("SomeRandomTextBeingNotified");
    }
}

尝试使用此选项时,无法使用自动属性。您需要创建备份存储:

private string _someRandomText;
public string SomeRandomText {
    get { return _someRandomText; }
    set 
    {
        _someRandomText = value;
        NotifyPropertyChanged("SomeRandomText");
    }
}

要使代码看起来更干净,可以使用INotifyPropertyChanged的属性


看看这个

实际上你可以,但是你基本上需要在C#编译器后更改字节码

这听起来可能需要做很多工作,但这是PostSharp所包含的更简单的后处理步骤之一

更多功能可用;)

否则请注意

在此处输入代码
在此处输入代码`NotifyPropertyChanged(“SomeRandomTextBeingNotified”)

这是错误的代码。我在一个字段更新方法中完成所有这些操作:

set 
{
    OnUpateField (ref _someRandomText, value);
}

update方法执行all-检查是否相等(当new value=old value时不希望触发),然后根据需要触发更新。它通过编译器自动设置的调用方法第三个参数获取属性名。备选方案使用LINQ语句(ref someRandomText,value,this->someRandomText)。我永远不会喜欢那里的字符串在重构时不会被重命名;)

如果您没有基类,像这样的东西非常灵活:

public class NotificationObject : INotifyPropertChanged
{
    private readonly Dictionary<string, object> Properties = new Dictionary<string, object>();

    public event PropertyChangedEventHandler PropertyChanged;

    protected TType Get<TType>(string propertyName)
    {
        object value;
        return Properties.TryGetValue(propertyName, out value) ? (TType)value : default(TType);
    }

    protected void Set<TType>(TType value, string propertyName, params string[] dependantPropertyNames)
    {
        Properties[propertyName] = value;
        OnPropertyChanged(propertyName);
        if (dependantPropertyNames != null)
        {
            foreach (string dependantPropertyName in dependantPropertyNames)
            {
                OnPropertyChanged(dependantPropertyName);
            }
        }
    }

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArts(propertyName));
        }
    }
}
公共类NotificationObject:INotifyPropertChanged
{
私有只读字典属性=新字典();
公共事件属性更改事件处理程序属性更改;
受保护的TType Get(字符串属性名称)
{
目标价值;
返回属性.TryGetValue(propertyName,out值)?(TType)值:默认值(TType);
}
受保护的无效集(TType值、字符串propertyName、参数string[]DependentPropertyNames)
{
属性[propertyName]=值;
OnPropertyChanged(propertyName);
if(DependentPropertyNames!=null)
{
foreach(DependentPropertyName中的字符串DependentPropertyName)
{
OnPropertyChanged(依亲财产名称);
}
}
}
受保护的无效OnPropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArts(propertyName));
}
}
}
可以这样使用:

public SomeObjectThatNeedsToNotifySomething : NotificationObject
{
    public int SomeValue
    {
        get { return Get<int>("SomeValue"); }
        set { Set<int>(value, "SomeValue", "SomeAggregateValue"); }
    }

    public int SomeOtherValue
    {
        get { return Get<int>("SomeOtherValue"); }
        set { Set<int>(value, "SomeOtherValue", "SomeAggregateValue"); }
    }

    public int SomeAggregateValue
    {
        get { return SomeValue + SomeOtherValue; }
    }
}
public someobjects需要通知:NotificationObject
{
公共int值
{
get{return get(“SomeValue”);}
set{set(value,“SomeValue”,“SomeAggregateValue”);}
}
公共int其他值
{
获取{return get(“SomeOtherValue”);}
set{set(value,“SomeOtherValue”,“SomeAggregateValue”);}
}
公共int-SomeAggregateValue
{
获取{return SomeValue+SomeOtherValue;}
}
}

如果您已经有一个基类,并且只需要实现INotifyPropertyChanged接口,@Rob是正确的,请提供一个支持字段并触发事件。

没有半自动属性。尽管如此,仍有许多实现INotifyPropertyChanged的方法不需要繁琐的命令式代码

1) 前面提到:PostSharp,一个面向方面的商业项目

2) 创建Castle DynamicProxy解决方案。可以找到一个样本,实际上还有很多其他的样本


在通用解决方案上投入一些时间是值得的,样板代码可能会在一段时间后变得烦人,并且容易出错。

你就是做不到。对于getter和setter,您需要使用字段并在属性中明确引用它们执行所有其他需要的处理,如调用
NotifyPropertyChanged
。实际上您可以,但您需要对字节码进行后处理,就像postsharp一样。@TomTomTom这是真的,但我不确定在这种情况下是否值得麻烦。噢。但愿它被允许。代码看起来会更干净(如果您将答案标记为已接受,将不胜感激。可能更重要的是:您可能希望将此作为反馈提交到Microsoft Connect网站for Visual Studio。@Harsha我认为这样做不会更干净。如果我们假设您问题中的第二个示例是可能的,编译器如何知道它是自动属性还是您实际需要的我做了一些事情,没有设置任何支持字段?啊-代码分析?就像任何非愚蠢的工具一样。如果PostSharp能做到这一点,编译器也能做到。@Guillame:是的。我理解这一部分。我问这个问题只是为了证实这一点。:)