【问题标题】:ListBox not refreshing SelectedItem when DataSource is updated and new source has a different object that 'equals' SelectedItem当 DataSource 更新并且新源具有“等于”SelectedItem 的不同对象时,ListBox 不刷新 SelectedItem
【发布时间】:2014-03-11 16:58:06
【问题描述】:

我有一个绑定到 ListCollectionView 的 ListBox,有一次我在列表框中选择了一个项目,然后我将重新创建 ListCollectionView,但 ListBox 在内部保留对旧列表中项目的引用.这是一个问题,因为该项目有一个对其父容器的引用,它实际上会导致内存泄漏。

这是来自 .NET 内存分析器的屏幕截图,显示了 ListBox 的 SelectedItem 和 SelectedValue 如何保持对 DataPoint 对象的引用。

新 ListCollectionView 中的新 DataPoint 对象等于现有的选定对象(因为它有自己的标识符字段并且我覆盖了 object.Equals)但不是同一个引用,如何强制 ListBox 更改其 SelectedItems这样就不会导致内存泄漏?有没有比从后面的代码中强行取消选择并重新选择项目更好的方法?

目前 WPF 的外观如下:

<!-- Listbox of items -->
<ListBox
    x:Name="ListBoxOfStuff"
    ItemsSource="{Binding ListView}"
    ItemTemplate="{Binding ItemTemplate}"

而在我背后的代码中

public ListCollectionView ListView
{
    get { return _listview; }
    private set
    {
        if (_listview == value)
            return;

        _totalItemsInCollection = value.Count;
        _listview = value;
        _listview.Filter = this.ApplyFilter;

        RaisePropertyChanged("ListView");
        RaisePropertyChanged("FilteredInCount");
    }
}

【问题讨论】:

  • 我总是做的只是将SelectedItem 绑定到 ViewModel 上的一个属性。这样我总是可以指示选择了哪个项目(这是一种经常出现的模式),以及在项目不再存在时将其清除(例如,在刷新其源集合时)。大功告成。
  • @Will 我可以在选择模式为扩展时绑定到 SelectedItem 并且他们可以选择多个项目吗?
  • @BrandonAGr:在这种情况下是 SelectedItems。这应该是一个 DependencyProperty,至少在当前版本的框架中。

标签: c# wpf mvvm listbox


【解决方案1】:

cmets(上图)是否解决了您的问题?威尔的建议听起来像你需要的。这就是我一直在做的事情——在绑定到 SelectedItem 的视图模型上有一个单独的属性,或者如果您将其用作多选列表框:SelectedItems(它是一个集合)。当一个新集合分配给您的绑定属性时,应该释放以前的集合。如果不是(并且在某些情况下我已经发生了这种情况)通过使绑定无效来重新绑定,总是为我清除它。您还可以检查以确保其他东西没有保留对该项目的引用。例如,我看到一个引发事件的实现,其中包含对列表项的 SelectedItem 的引用。它不是弱引用,它徘徊,导致内存泄漏。解决方法是在该事件中提供一个 ID,用于识别用户刚刚选择的项目,但不是实际的参考。您正在做正确的事情,使用您的分析器检查内存情况(荣誉)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-30
    • 2021-09-26
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多