【问题标题】:ObservableCollection Behavior in MVVM Child InstanceMVVM 子实例中的 ObservableCollection 行为
【发布时间】:2012-09-17 20:42:03
【问题描述】:

我有一个奇怪的行为。我正在使用 MVVM 模式,我将一个名为 AlarmCollection 的 Observable 集合绑定到一个名为 AlarmView 的视图中的网格控件。当我创建一个 AlarmModelView 类的多个实例并将项目添加到 AlarmCollection 时,所有实例都会显示更改。

对 ObservableColelction AlarmCollection 的任何更改都会影响网格控件的所有绑定 ItemSource。

我曾尝试锁定调度程序线程,来自此处的类似帖子,但无济于事。

是否无论如何都要在 ViewModel 的每个实例中保留对这个 Observable 集合的更改?这样每次修改都不会影响 UI 线程中的任何其他集合。

感谢任何帮助。

[在下面编辑]
这是一个奇怪的场景,我需要通过创建子 MV 的新实例来放大/钻取呈现的内容,这反过来又将选项卡添加到父 MV。子视图都绑定到相同的集合名称,并且都由 WCF 异步调用更新。根据缩放级别的深度,我需要 X 个多个实例,所以我需要 1 个 ModelView 对象。

我将如何使用 CollectionChanged 事件或创建 ModelView 自己的 CollectionView 来实现这一点?

    private MainViewModel _parentViewModel;
    public MainViewModel ParentViewModel
    {
        get { return _parentViewModel; }
        set
        {
            if (ParentViewModel == value) { return; }

            SetPropertyValue(ref _parentCircuitViewModel, value, "ParentViewModel");
        }
    }



    private ObservableCollection<DetailEntity> _alarmCollection;
    public ObservableCollection<DetailEntity> AlarmCollection
    {
        get
        {
            if (_alarmCollection == null)
                _alarmCollection = new ObservableCollection<DetailEntity>();

            return _alarmCollection;
        }
        private set { _alarmCollection = value; }
    }

    ServiceNode _selectedNode;

    public ServiceNode SelectedNode
    {
        get { return _selectedNode; }
        set 
        { 
                SetPropertyValue(ref _selectedNode, value, "SelectedNode");

                // render selected child node service path
                RenderSubPath(_selectedNode);

                // reset storage value
                _selectedCircuitNode = null;

        }
    }

    // Constructor
    public RenderViewModel(string servicePath  CircuitMainViewModel parentViewModel)
    {
        ServicePath = servicePath,
        ParentCircuitViewModel = parentViewModel;


        // event to handler for completed async calls 
        Client.GetAlarmsByNodeListCompleted += new EventHandler<GetAlarmsByNodeListCompletedEventArgs>(Client_GetAlarmsByNodeListCompleted);

    }

     void RenderSubPath(ServiceNode childNode)
     {
        if (childNode == null)
            return;
            // create a new child instance and add to parent VM tab
                _parentViewModel.AddServiceRenderTab(new ViewModel.Workspaces.RenderViewModel(childNode.elementPath _parentViewModel);
     }

      // wcf async webservice call to add alarm to ObservableCollection
      // ** This is updating all Collections in all Views.
      void Client_GetAlarmsByNodeListCompleted(object sender, AlarmServiceReference.GetAlarmsByNodeListCompletedEventArgs e)
      {
          try
          {
              if (e.Result == null)
                  return;

              // add to parent Netcool alarm collection
              foreach (DetailEntity alarm in nodeAlarms)
              {
                  _alarmCollection.Add(alarm);
              }

          }
     }

【问题讨论】:

  • 您的所有视图是否都绑定到同一个ObservableCollection
  • 看起来你的所有视图都绑定到同一个集合,这个结果是正常的!你应该只创建不同的列表,每个视图一个
  • 感谢您的回复,我重新发布了一些代码。

标签: c# wpf mvvm


【解决方案1】:

根据您的描述,听起来您的所有视图都绑定到同一个底层集合。对于您绑定到的任何集合,WPF 实际上将绑定到围绕该集合的集合视图 (ICollectionView)。如果您没有明确创建自己的集合视图,它将使用默认视图。对同一个集合的任何绑定都将导致使用同一个集合视图。

如果没有看到您的代码就很难说,但您可能想要使用底层视图模型的单独实例(以及因此的集合),或者您想要显式创建单独的集合视图并绑定到它们.

【讨论】:

  • 这是一个奇怪的场景,我正在渲染并且需要通过创建子 MV 的新实例来缩放/钻取渲染的内容,这反过来又将选项卡添加到父 MV。子视图都绑定到相同的集合名称,并且都在更新。根据缩放级别的深度,我需要 X 个多个实例,所以我需要 1 个实例。我将如何创建将包含在实例中的 CollectionView? (我将在我的原始答案中更新代码)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
  • 2014-06-26
  • 1970-01-01
相关资源
最近更新 更多