【发布时间】:2012-08-16 15:39:14
【问题描述】:
我遇到了一个问题,我在DataModel 和ViewModel 与PropertyChanged event 之间陷入了无限循环。
我的结构:
public class SomeDataModel : DataModelBase
{
public SomeDataModel()
{
}
public object SomeProperty
{
get
{
//
}
set;
{
//
OnPropertyChanged("SomeProperty");
}
}
public bool SomeMethod()
{
SomeProperty = SomeNewObject
}
}
public class SomeViewModel : ViewModelBase
{
public SomeViewModel()
{
}
public SomeDataModel SomeDataModel
{
get;
set;
}
public object SomeProperty
{
get
{
return SomeDataModel.SomeProperty;
}
set
{
SomeDataModel.SomeProperty = value;
OnPropertyChanged("SomeProperty");
}
}
}
ViewModel 和 DataModel 都实现了 INotifyPropertyChanged。
然后我的ViewModelBase 中有一个listener 用于在我的DataModel 中更改的任何property:
private void DataModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
PropertyInfo toPropertyInfo = this.GetType().GetProperty(e.PropertyName);
PropertyInfo fromPropertyInfo = DataModel.GetType().GetProperty(e.PropertyName);
if (toPropertyInfo != null && fromPropertyInfo != null)
{
if (toPropertyInfo.CanWrite && fromPropertyInfo.CanRead)
{
toPropertyInfo.SetValue(this, fromPropertyInfo.GetValue(DataModel, null), null);
}
}
}
所以现在当property 在DataModel 中设置时,ViewModelBase 中的侦听器会捕获它并更新ViewModel 中的相关property。但是ViewModel 中的集合将其设置回DataModel,导致OnPropertyChanged("SomeProperty"); 再次触发,以无限循环结束。
- 是否有快速解决方法来解决它? (注意:不能改变结构)
- 我是否能够创建自己的自定义类,继承自
PropertyChangedEventArgs并且我的INotifyPropertyChanged操作仍然有效?
我在想:
public class CustomPropertyChangedEventArgs : PropertyChangedEventArgs
{
public CustomPropertyChangedEventArgs(string propertyName, SomeEnum enumName)
: base(propertyName)
{
//Set enum
}
}
然后在OnPropertyChanged 中我想使用新的CustomPropertyChangedEventArgs 并传递我想使用的enum。
public void OnPropertyChanged(string propertyName)
{
CustomPropertyChangedEventArgs handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new CustomPropertyChangedEventArgs(propertyName, newEnum));
}
}
【问题讨论】:
-
我可能会被炸死,但我放了一个类级别列表,其中列出了每个对象中当前正在更改的所有属性名称(检查并在输入方法时添加并在退出方法时删除)。如果,当我输入 OnPropertyChanged 时,属性名称已经在列表中,我只是返回而不做任何事情。我宁愿不刷新也不愿冒无限循环的风险。
-
是的,我会在代码审查中抨击你。 :)
-
Amiram Korach 有最好的方法,只要您可以确定没有人会调用 OnPropertyChanged,而是调用属性集代码。否则总会有无限循环的风险。我会对愤怒的用户和崩溃的程序进行差评 =)