重新加载 ItemsSource 时如何保留 ListBox 中的选择
我正在我们的系统中试验 WPF 和 MVVM。然而,我在仅使用 MVVM (不执行额外的 CollectionViews )在列表中保留所选内容时遇到了问题。 我当前拥有的是列表
ObservableCollection<ReservationCustomerList> Customers;
,然后是存储所选客户的属性
ReservationCustomerList SelectedCustomer;
现在我认为,当列表重新加载时(实际上是从另一个线程异步),选择应该能够保留,但是这不会发生。
有人有一个干净的方法来实现这一目标吗?
I am experimenting with WPF and MVVM in our system. However iam having a problem with keeping things selected in lists using only MVVM ( without doing extra CollectionViews ).
What i currently have is the list
ObservableCollection<ReservationCustomerList> Customers;
And then a property storing the selected Customer
ReservationCustomerList SelectedCustomer;
In my opinion now, when the list reloads (actually from another thread async), the selection should be able to be kept, however this does not happen.
Does someone have a nice clean way of achieving this ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我们的做法是不更换集合。我们添加/删除了条目,并根据需要更新了现有条目。这将维持选择。
您可以使用 except 等 LINQ 方法来标识新项目或已删除项目。
The way we did it was that we did not replace the collection. We added/removed the entries and updated existing entries if required. This maintains the selection.
You can use LINQ methods like Except to identify items that are new or removed.
如果重新加载的列表仍包含最后选定的项目,并且您希望选择该项目,则可以在集合重新加载后引发属性
SelectedCustomer
的PropertyChange
事件。请确保您的 viewmodel 类实现了 INotifyPropertyChanged 接口。
In case the reloaded list still contains the last selected item and you want that item to be selected, then you can raise the
PropertyChange
event for the propertySelectedCustomer
after your collection gets reloaded.Please make your sure your viewmodel class implements
INotifyPropertyChanged
interface.您可以使用 ICollectionView 来选择所需的实体。
在 Xaml 中,itemsControl 必须具有 IsSynchronizedWithCurrentItem=true
,或者如果 ItemsControl 具有 SelectedItem 属性,您只需将其绑定到 SelectedCustomer 属性即可。
you can use the ICollectionView to select the entity you want.
in your Xaml the itemsControl must have IsSynchronizedWithCurrentItem=true
or if the ItemsControl has a SelectedItem property you can simply bind it to your SelectedCustomer Property.
当您“重新加载”集合时,您基本上将其中的所有值替换为新值。即使那些外观和感觉相同的产品实际上也是新产品。那么,当列表中的同一项目消失时,您如何引用它呢?您当然可以使用 hack,确定通过其属性选择的项目并重新选择它(即通过列表进行 LINQ 搜索并返回匹配项目的 ID,然后重新选择它)。但这肯定不是使用最佳实践。
您实际上应该只更新您的集合,即删除无效条目并添加新条目。如果您有一个连接到您的集合的视图,那么所有排序和选择之类的操作都将在幕后自动完成。
编辑:
在重置/清除对我有用的方法中。即,这是我放入示例应用程序中按下刷新按钮时调用的事件处理方法中的代码。这样,您甚至不需要保留对客户对象的引用,只要您确保您的 ID 是一致的即可。我尝试过的其他方法,例如覆盖集合“ClearItems()”方法以及覆盖“Equals()”和“GetHashCode()”都不起作用 - 正如我所预期的那样。
When you "reload" your collection you basically replace all values in it with new values. Even those that look and feel identical are in fact new items. So how do you want to reference the same item in the list when it is gone? You could certainly use a hack where you determine the item that was selected by its properties and reselect it (i.e. do a LINQ search through the list and return the ID of the matching item, then reselect it). But that would certainly not be using best practices.
You should really only update your collection, that is remove invalid entried and add new entries. If you have a view connected to your collection all the sorting and selecting and whatnot will be done automagically behind the scenes again.
Edit:
in the method that does the reset/clear works for me. I.e. that is the code I put into the event handling method called when pressing the refresh button in my sample app. That way you dont even need to keep references to the customer objects as long as you make sure that whatever your ID is is consistent. Other things I have tried, like overwriting the collections ´ClearItems()´ method and overwriting ´Equals()´ and ´GetHashCode()´ didn't work - as I expected.