如何在更新后将绑定到 CollectionViewSource 的 ListView 滚动到所需的项目

How to scroll a ListView bound to a CollectionViewSource to a desired item after it's update

我目前正在开发一个 WinRT 应用程序,需要一个按日期排序并按天分组的 ListView。 ListView 绑定到我的 ViewModel

中的 ICollectionView
public Windows.UI.Xaml.Data.ICollectionView GroupedData { 
        get
        {
            return cvSource.View;
        }  
    }

private Windows.UI.Xaml.Data.CollectionViewSource cvSource;

在我的 XAML 中,我可以将 ListView 绑定到这个 属性:

<ListView ItemsSource="{Binding GroupedData}" 

现在我正在对存储在 List<> 中的基本数据进行一些计算和过滤。完成此操作后,分组通过 LINQ 进行:

var result = from DataObject in basicData 
                  group DataObject by DataObject.Date 
                  into date_grp orderby date_grp.Key 
                  select date_grp;

最后我将 CollectionView 的源设置为这个新结果并触发 OnPropertyChanged

cvSource.Source = result.ToList();
OnPropertyChanged("GroupdedData");

这按我的预期工作,但 ListView 现在 select 是我每次填充新源时的第一个元素。我按照 Whosebug by sellmeadog

中的描述摆脱了这个

现在我喜欢手动 select 一个项目。这应该是更改 CollectionView 的源之前的前一个 selected 项目。保存前一个项目的最佳方法是什么,看看它是否在新创建的 CollectionView 中,select 它并滚动到它?

此致

对于selecting senario,在ViewModel中添加一个新的属性并绑定ListView的SelectedItem 属性:

public Windows.UI.Xaml.Data.ICollectionView GroupedData { 
    get
    {
        return cvSource.View;
    }  
}
public YourObjectType CurrentItem {
    get {
        return this.currentItem;
    }
    set {
        if (this.currentItem != value) {
            this.currentItem  = value;
            this.OnPropertyChanged("CurrentItem");
        }
    }
}
private YourObjectType currentItem;
private Windows.UI.Xaml.Data.CollectionViewSource cvSource;

然后在设置源之前,保持对当前项目的引用

var current = this.CurrentItem;
cvSource.Source = result.ToList();
this.CurrentItem = current;

假设您的 DataObjects 类型覆盖了 Equals 方法,ListView 会在集合中找到并选择它。如果没有,您可能需要添加代码以在新集合中查找它的实例并将其分配给 CurrentItem 属性.

但是选择项目并不意味着 ListViewScrolls 到它。您可能需要调用 ListView.BringIntoView 才能滚动到所选项目。

你需要ObservableComputations。使用这个库你可以这样编码:

private INotifyCollectionChanged _groupedData
public INotifyCollectionChanged GroupedData =>
 _groupedData = _groupedData ?? basicData.Grouping(dataObject  => dataObject.Date)
      .Selecting(date_grp => date_grp.Key);

GroupedData反映了basicData集合中的所有变化。不要忘记将 INotifyPropertyChanged 接口的实现添加到 DataObject class,以便 GroupedData 集合反映 dataObject.Date 属性 中的更改。 GroupedData 是单例实例,因此您不会丢失 ListView 中的项目选择。