【问题标题】:Mvvm nested propertychanged in model模型中的 Mvvm 嵌套属性已更改
【发布时间】:2012-04-30 22:07:57
【问题描述】:

我使用模型类 A,其中包含模型类 B 的列表。每个模型(A 和 B)都实现 INotifyPropertyChanged,并且在属性更改时正确触发事件。模型 A 已从模型 B 订阅了此事件,如果发生此事件,模型 A 会触发另一个更改的属性。

我的问题是我想在应该将更改写入数据库的服务类中监听模型 A(包括嵌套模型属性)中的更改。但是,当模型 A 触发 propertychanged 时,在我的服务类中,我无法知道已更改的属性是属于模型 A 还是属于模型 B 之一。

public class Model B : ObservableObject
{
...
  public int Property1
  {
    get{return property1;}
    set{ this.property1 = value;
         OnPropertyChanged("Property1");  
       }
  }
} 


public class ModelA : ObservableObject
{
 ...
 ObservableCollection<ModelB> modelsB;
 ...

 public ObservableCollection<ModelB> ModelsB
 {
   get
   {
     if(modelsB == null)
     {
       this.modelsB = new ObservableCollection<ModelB>();
       this.modelsB.CollectionChanged+= ModelBListChanged;
     }
     return modelsB;
   }
 }


  private int property2;
  public int Property2
  {
    get{return property2;}
    set{ this.property2 = value;
         OnPropertyChanged("Property2");  
       }
  }

 private void ModelBListChanged(object sender, NotifyCollectionChangedEventArgs args)
 {
    if(e.NewItems != null)
      {
        foreach(ObservableObject item in e.NewItems)
        {
          item.PropertyChanged += NotifyPropertyChanged;
        }
      }
      if (e.OldItems != null)
      {
        foreach (ObservableObject item in e.OldItems)
        {
          item.PropertyChanged -= NotifyPropertyChanged;
        }
      }
 }

 ...

}


public class SomeService
{
   ...

  ObservableCollection<ModelA> modelsA;

  public ObservableCollection<ModelA> ModelsA
  {
     get
     {
       if(modelsA == null)
       {
         modelsA = new ObservableCollection<ModelA>();

             //fill with data...
         ....
         foreach(...)
         {
        ModelB mb = new ModelB();
            //fill mb ...
        ...

        mb.PropertyChanged += ModelBChanged;
        modelsA.ModelsB.Add(mb);
         }
         ....
         modelsA.PropertyChanged += ModelsAChanged;
       }
       return modelsA;
     }
  }

  ...

  private void ModelsAChanged(object sender, PropertyChangedEventArgs args)
  {
    // determine the property that has changed and call the correct
    // update function for this property to write the data to database.

var ma = (ModelA) sender;

      switch(args.PropertyName)
      {
     ...
        case ModelA.Property1:
          //update database with function for property 1
          break;
        case ModelA.Property2:
          //update database with function for property 2
          break;
     ...
      }
  }

  private void ModelBChanged(object sender, PropertyChangedEventArgs args)
  {
    // How do I know to which ModelA this ModelB sender belongs?

var mb = (ModelB) sender;
switch(args.PropertyName)
      {
     ...
        case ModelB.Property1:
          //update database with function for property 1 of model B
          break;
       ...
      }
  }
}

如何解决?

问候,

塔比娜

【问题讨论】:

    标签: c# mvvm model nested inotifypropertychanged


    【解决方案1】:

    我不确定您当前的代码是否可以编译?您正在将 B 集合中的 CollectionChanged 事件转换为 A 类上的 PropertyChanged 事件,但您引用的 PropertyNameNotifyCollectionChangedEventArgs 中不存在。

    即使你可以让它工作,也没什么意义,因为CollectionChanged 事件可以引用多个项目,而PropertyChanged 只能引用一个。

    您的 B 集合已经是 A 的公共财产。为什么您不能直接订阅服务中的更改?例如。

    public class SomeService
    {
        ObservableCollection<ModelA> modelsA;
    
        public ObservableCollection<ModelA> ModelsA
        {
            get
            {
                if(modelsA == null)
                {
                   modelsA = new ObservableCollection<ModelA>();
                   //fill with data...
    
                   modelsA.CollectionChanged += ModelsAChanged;
    
                   foreach (ModelA A in modelsA)
                       A.ModelsB.CollectionChanged += ModelsBChanged;
                }
    
                return modelsA;
            }
        }
    
        private void ModelsAChanged(object sender, NotifyCollectionChangedEventArgs args)
        {
            //remember to subscribe to ModelsB in any new ModelA instance that get added 
            //to the modelsA collection too, and unsubscribe when they get removed.
        }
    
        private void ModelsBChanged(object sender, NotifyCollectionChangedEventArgs args)
        {
    
        }
    }
    

    【讨论】:

    • 你是对的。它应该是 PropertyChangedEvent 而不是 CollectionChanged。我把它弄混了写这篇文章。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    相关资源
    最近更新 更多