I have come across an issue where i get in an endless loop between my DataModel
and ViewModel
with PropertyChanged event
.
My structure:
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");
}
}
}
Both ViewModel
and DataModel
implements INotifyPropertyChanged
.
Then i have a listener
in my ViewModelBase
for any property
that changes in my 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);
}
}
}
So now when the property
gets set in the DataModel
, the listener in ViewModelBase
catches it and updates the relevant property
in the ViewModel
. But the set in the ViewModel
sets it back to the DataModel
with causes OnPropertyChanged("SomeProperty");
to fire agian, ending in a endless loop.
PropertyChangedEventArgs
and still have my INotifyPropertyChanged
operations working? I was thinking:
public class CustomPropertyChangedEventArgs : PropertyChangedEventArgs
{
public CustomPropertyChangedEventArgs(string propertyName, SomeEnum enumName)
: base(propertyName)
{
//Set enum
}
}
and then in OnPropertyChanged
i want to use the new CustomPropertyChangedEventArgs
and pass the enum
in that i want to use.
public void OnPropertyChanged(string propertyName)
{
CustomPropertyChangedEventArgs handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new CustomPropertyChangedEventArgs(propertyName, newEnum));
}
}
You can check if the value is the same and don't update it. This is how usually INotifyPropertyChanged
is implemented. You fire the OnPropertyChanged
only if it really changed.
public object SomeProperty
{
get
{
return SomeDataModel.SomeProperty;
}
set
{
if (SomeDataModel.SomeProperty != value)
{
SomeDataModel.SomeProperty = value;
OnPropertyChanged("SomeProperty");
}
}
}
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.