首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为INotifyPropertyChanged接口创建自己的INotifyPropertyChanged?

如何为INotifyPropertyChanged接口创建自己的INotifyPropertyChanged?
EN

Stack Overflow用户
提问于 2012-08-16 15:39:14
回答 2查看 4.4K关注 0票数 0

我遇到了一个问题,在我的DataModelViewModelPropertyChanged event之间有一个没完没了的循环。

我的结构:

代码语言:javascript
复制
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");
        }
    }
}

ViewModelDataModel都实现了INotifyPropertyChanged

然后,我的ViewModelBase中有一个ViewModelBase,用于任何在DataModel中更改的property

代码语言:javascript
复制
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);
        }
    }
}

因此,现在当propertyDataModel中设置时,ViewModelBase中的侦听器会捕获它并在ViewModel中更新相关的property。但是ViewModel中的集合将其设置为DataModel,并导致OnPropertyChanged("SomeProperty");触发agian,以一个无休止的循环结束。

  1. 有没有快速修复它的方法?(Note:无法更改结构)
  2. 我是否能够创建我自己的自定义类,从PropertyChangedEventArgs继承,并使我的INotifyPropertyChanged操作仍然正常工作?

我在想:

代码语言:javascript
复制
public class CustomPropertyChangedEventArgs : PropertyChangedEventArgs
{
    public CustomPropertyChangedEventArgs(string propertyName, SomeEnum enumName)
        : base(propertyName)
    {
        //Set enum
    }
}

然后,在OnPropertyChanged中,我想使用新的CustomPropertyChangedEventArgs,并传递想要使用的enum

代码语言:javascript
复制
public void OnPropertyChanged(string propertyName)
{
    CustomPropertyChangedEventArgs handler = this.PropertyChanged;

    if (handler != null)
    {
        handler(this, new CustomPropertyChangedEventArgs(propertyName, newEnum));
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-16 15:47:09

您可以检查该值是否相同,并且不更新它。这就是通常实现INotifyPropertyChanged的方式。只有当OnPropertyChanged 真正改变了时,才会触发。

代码语言:javascript
复制
public object SomeProperty
{
    get
    {
        return SomeDataModel.SomeProperty;
    }
    set
    {
        if (SomeDataModel.SomeProperty != value)
        {
            SomeDataModel.SomeProperty = value;
            OnPropertyChanged("SomeProperty");
        }
    }
}
票数 5
EN

Stack Overflow用户

发布于 2012-08-16 15:56:04

代码语言:javascript
复制
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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11990801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档