简体   繁体   English

将更改的模型列表同步到ViewModel的ObservableList的最佳实践?

[英]Best practice for synchronizing a changing List of the model to a ObservableList of the ViewModel?

I have an (external) model exposing a List that constantly changes (let's say every two seconds or so). 我有一个(外部)模型暴露一个不断变化的List(假设每两秒左右)。 A ViewModel knows that list registering for PropertyChange events. ViewModel知道该列表注册了PropertyChange事件。 That ViewModel also provides an ObservableCollection to the UI for data binding. ViewModel还为UI提供了一个ObservableCollection以进行数据绑定。

+-----------------------------------------------+
|                                           View|
| +-----------+                                 |
| |Listbox    |                                 |
| +-----------+                                 |
+-----/\----------------------------------------+
      ||
      ||DataBinding
      ||
      ||
+-----||----------------------------------------+
|     ||                               ViewModel|
| +--------------------+         +-------------+|
| |ObservableCollection|<--------|ChangeHandler||
| +--------------------+    /    +-------------+|
|                          /           ^        |
+-------------------------/------------|--------+
                         /             |
                        /              |
           Synchronizing Lists         | PropertyChanged
                                       |
                                       |
+--------------------------------------|--------+
|                                  +-----+ Model|
|                                  |IList|      |
|                                  +-----+      |
|                                               |
+-----------------------------------------------+

In principle that works well, besides the updates conducted constantly. 除了不断进行的更新之外,原则上它运作良好。 With every update the user looses his selection, ie all items will be deselected with every update. 每次更新时,用户都会放弃他的选择,即每次更新都会取消选择所有项目。 This is no wonder, as WPF's ListBox "sees" that a new list was assigned. 这也就不足为奇了,因为WPF的ListBox“看到”分配了一个新列表。

So, the thing must be that we do not assign a new ObservableCollection, but merge the content of the current ObservableCollection with the updated Model.List 所以,事情必须是我们分配新的ObservableCollection,而是将当前ObservableCollection的内容与更新的Model.List合并。

Now my questions 现在我的问题

  • Synchronizing Lists - Are there best practices (or frameworks) on how to do such a merge (Copy new items to ObservableCollection, Deleting missing ones, updating altered items) 同步列表 - 是否有关于如何进行此类合并的最佳实践(或框架)(将新项目复制到ObservableCollection,删除丢失的项目,更新更改的项目)
  • Selected Item - How can I assure that the ListBox keeps the currently selected item (besides the case that item was removed) 选定项目 - 如何确保ListBox保留当前选定的项目(除了项目已被删除的情况)

You can either generate a new ObservableCollection from the updated model list or sync the current ObservableCollection with the model's one. 您可以从更新的模型列表生成新的ObservableCollection,也可以将当前的ObservableCollection与模型的同步。

If you go for the second, one thing you may want to avoid is to fire CollectionChanged events for every synced item. 如果您选择第二个,您可能想要避免的一件事是为每个同步项启动CollectionChanged事件。 Take a look at this ObservableCollection implementation which has the hability to defer the notifications. 看看这个ObservableCollection实现 ,它具有推迟通知的能力。

As for keeping the current SelectedItem, if the instance of the ObservableCollection isn't changed (what is true, because we are syncing the collections) and the SelectedItem instance isn't removed, the listbox should hold the selection. 至于保持当前的SelectedItem,如果未更改ObservableCollection的实例(这是真的,因为我们正在同步集合)并且未删除SelectedItem实例,则列表框应保留选择。 However, I'm not certain if that is true if the NotifyCollectionChangedEventArgs.Action is "Reset". 但是,如果NotifyCollectionChangedEventArgs.Action为“Reset”,我不确定是否属实。 If that's the case, you can use the approach I use, which is to have both a colllection property and a SelectedItem property in the ViewModel. 如果是这种情况,您可以使用我使用的方法,即在ViewModel中同时具有colllection属性和SelectedItem属性。 You bind the ViewModel's SelectedItem to the ListBox.SelectedItem in TwoWay mode. 您将ViewModel的SelectedItem绑定到TwoWay模式下的ListBox.SelectedItem。 When you synchronize the Collections, you save the SelectedItem in a temp variable and then reapply it, if it wasn't removed, after the synchronization. 同步集合时,将SelectedItem保存在临时变量中,然后在同步后重新应用它(如果未删除)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM