感谢Marc Gravell的精彩answer我能够在课堂上实现属性更改跟踪。但是,首次初始化对象并首次设置属性时,所有属性都被标记为脏。处理属性初始设置的最佳方法是什么,以便在首次加载对象时不会将它们标记为脏?
因此,首次设置ExtendedFieldDto
属性时,dirtyProperties
的计数始终等于继承类的属性,在本例中为ExtendedFieldDto
。
public abstract class NotifyPropertyChanged {
public IDictionary<string, object> dirtyProperties { get; private set; }
protected NotifyPropertyChanged() {
dirtyProperties = new Dictionary<string, object>();
}
protected void setProperty<T>(ref T property, T value, string propertyName) {
if (!EqualityComparer<T>.Default.Equals(property, value)) {
property = value;
if (dirtyProperties.Keys.Contains(propertyName))
dirtyProperties[propertyName] = property;
else
dirtyProperties.Add(propertyName, property);
}
}
}
public class ExtendedFieldDto : NotifyPropertyChanged {
private string _id;
public string id {
get { return _id; }
set { setProperty(ref _id, value, "id"); }
}
private int _idLocation;
public int idLocation {
get { return _idLocation; }
set { setProperty(ref _idLocation, value, "idLocation"); }
}
private string _columnName;
public string columnName {
get { return _columnName; }
set { setProperty(ref _columnName, value, "columnName"); }
}
private string _description;
public string description {
get { return _description; }
set { setProperty(ref _description, value, "description"); }
}
private string _help;
public string help {
get { return _help; }
set { setProperty(ref _help, value, "help"); }
}
}
dto目前被用作aspx页面上的proprety,我将对象存储在ViewState
中(遗留代码的要求)。所以我不确定如何使用ExtendedFieldDto
的构造函数来设置这种类型的私有属性。
private ExtendedFieldDto extendedField {
get {
if (ViewState[EXTENDED_FIELD_VIEWSTATE_KEY] == null)
ViewState[EXTENDED_FIELD_VIEWSTATE_KEY] = new ExtendedFieldDto();
return (ExtendedFieldDto)ViewState[EXTENDED_FIELD_VIEWSTATE_KEY];
}
set { ViewState[EXTENDED_FIELD_VIEWSTATE_KEY] = value; }
}
答案 0 :(得分:5)
这是创建ISupportInitialize接口的众多常见问题之一。
public abstract class NotifyPropertyChanged : ISupportInitialize {
...
public void BeginInit() { }
public void EndInit() { PropertyChangedObserver(); }
}
你可以这样使用它:
ExtendedFieldDto foo = new ExtendedFieldDto();
foo.BeginInit();
foo.id = "abc123";
foo.idLocation = 0;
...
foo.EndInit();
编辑:您可能也会考虑实施INotifyPropertyChanged,因为您已经完成了大部分工作。
答案 1 :(得分:0)
我有一次非常类似的问题。使用ctor的想法对我不起作用,因为该对象是通过XML反序列化创建和初始化的。
我使用的相当丑陋的解决方案是伪全局初始化bool变量(线程静态变量,http://msdn.microsoft.com/library/system.threadstaticattribute%28v=vs.110%29.aspx)。在反序列化数据之前,我将bool设置为true,并在反序列化完成后将其重置为false(使用try-finally结构是安全的)。在我的PropertyChanged处理程序中,我检查了那个bool。如果这是真的,我只是没有解雇我的事件。
这是一个非常难看的解决方案。我甚至不喜欢将它称为解决方案,因为每次调用PropertyChanged处理程序时都会检查该bool变量。它不是一种干净或保存方法,因为您必须确保在初始化期间仅设置该bool,并且必须确保之后重置它。但它对我有用。