C# 在类中使用INotifyPropertyChanged
C#允许创建如下属性:C# 在类中使用INotifyPropertyChanged,c#,wpf,C#,Wpf,C#允许创建如下属性: public string SomeRandomText { get; set; } 框架处理此属性的支持变量的创建。我如何拥有这样一个属性,并且仍然有更改通知 在实现INotifyPropertyChanged的类中允许这样做吗 public string SomeRandomTextBeingNotified { get; set { NotifyPropertyChanged("SomeRandomTextBeing
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:是的。我理解这一部分。我问这个问题只是为了证实这一点。:)