我遇到了一个问题,即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
。
然后我的listener
ViewModelBase
中property
DataModel
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
现在,当property
设置ViewModel
时,ViewModel
中的听众会抓住它并更新DataModel
中的相关OnPropertyChanged("SomeProperty");
。但是PropertyChangedEventArgs
中的集合将其设置回INotifyPropertyChanged
,原因public class CustomPropertyChangedEventArgs : PropertyChangedEventArgs
{
public CustomPropertyChangedEventArgs(string propertyName, SomeEnum enumName)
: base(propertyName)
{
//Set enum
}
}
会触发agian,以无限循环结束。
OnPropertyChanged
并且仍然可以使用CustomPropertyChangedEventArgs
操作?我在想:
enum
然后在public void OnPropertyChanged(string propertyName)
{
CustomPropertyChangedEventArgs handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new CustomPropertyChangedEventArgs(propertyName, newEnum));
}
}
我想使用新的{{1}}并传递我想要使用的{{1}}。
{{1}}
答案 0 :(得分:5)
您可以检查值是否相同但不更新。这通常是INotifyPropertyChanged
的实现方式。只有在真的更改时才会触发OnPropertyChanged
。
public object SomeProperty
{
get
{
return SomeDataModel.SomeProperty;
}
set
{
if (SomeDataModel.SomeProperty != value)
{
SomeDataModel.SomeProperty = value;
OnPropertyChanged("SomeProperty");
}
}
}
答案 1 :(得分:0)
you can disable and enable the event to avoid loop
private void DataModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
OnPropertyChanged -= DataModel_PropertyChanged;
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);
}
}
OnPropertyChanged += DataModel_PropertyChanged;
}