自己的 CollectionView 用于分页、排序和过滤

Posted

技术标签:

【中文标题】自己的 CollectionView 用于分页、排序和过滤【英文标题】:Own CollectionView for paging, sorting and filtering 【发布时间】:2013-03-27 05:51:28 【问题描述】:

我已经实现了自己的 CollectionView 来将数据集合绑定到 WPF 中的 DataGrid。

主要目标是分页,它工作得很好。 我编写了以下 C# 代码:

public class SchemesCollectionView : CollectionView

    private readonly IList<Scheme> innerList;
    private readonly int itemsPerPage;

    private int currentPage = 1;

    public SchemesCollectionView(IList<Scheme> source, int itemsPerPage)
        : base(source)
    
        innerList = source;
        this.itemsPerPage = itemsPerPage;
    

    public override int Count
    
        get  return itemsPerPage; 
    

    public int CurrentPage
    
        get  return currentPage; 
        set
        
            currentPage = value;
            OnPropertyChanged(new PropertyChangedEventArgs("CurrentPage"));
            OnPropertyChanged(new PropertyChangedEventArgs("FirstItemNumber"));
            OnPropertyChanged(new PropertyChangedEventArgs("LastItemNumber"));
        
    

    public int ItemsPerPage  get  return this.itemsPerPage;  

    public int PageCount
    
        get
        
            return (this.innerList.Count() + this.itemsPerPage - 1)
                / this.itemsPerPage;
        
    

    public int LastItemNumber
    
        get
        
            var end = currentPage * itemsPerPage - 1;
            end = (end > innerList.Count()) ? innerList.Count() : end;

            return end + 1;
        
    

    public int StartIndex
    
        get  return (currentPage - 1) * itemsPerPage; 
    

    public int FirstItemNumber
    
        get  return ((currentPage - 1) * itemsPerPage) + 1; 
    

    public override object GetItemAt(int index)
    
        var offset = index % (ItemsPerPage);

        var position = StartIndex + offset;

        if (position >= innerList.Count)
        
            position = innerList.Count - 1;
        

        return innerList[position];
    

    public void MoveToNextPage()
    
        if (CurrentPage < PageCount)
        
            CurrentPage += 1;
        
        Refresh();
    

    public void MoveToPreviousPage()
    
        if (CurrentPage > 1)
        
            CurrentPage -= 1;
        
        Refresh();
    

    public void MoveToFirstPage()
    
        CurrentPage = 1;
        Refresh();
    

    public void MoveToLastPage()
    
        CurrentPage = PageCount;
        Refresh();
    

如前所述,分页效果很好。但我无法进行过滤和排序工作。当我将自定义过滤器添加到 Filter 属性时,它会被完全忽略。排序也是一样。单击后我可以看到列标题上的箭头,但不同的排序不会反映在 DataGrid 中。

我在这里缺少什么?希望有人能帮忙。

【问题讨论】:

我遇到了同样的问题,并且指向 Silverlight 的链接已失效。请问你是怎么解决这个问题的? 【参考方案1】:

如本文所述,您可以从 Silverlight 获取代码并在 WPF 中使用。

Paged Collection View in WPF

【讨论】:

谢谢。来源看起来不错。我已将其复制到我的项目中,但每次我想使用分页(例如向前一页)时,我都会收到“集合已修改;枚举操作无法执行”。错误。不知道为什么以及如何解决这个问题。【参考方案2】:

这是一个仅使用 CollectionView 类进行过滤和分页的解决方案。

您只需要设置当前页面索引和每页最大项目数即可满足您的需求。

        // obtenir la CollectionView 
        ICollectionView cvCollectionView = CollectionViewSource.GetDefaultView(this.Suivis);
        if (cvCollectionView == null)
            return;

        // filtrer ... exemple pour tests DI-2015-05105-0
        cvCollectionView.Filter = p_oObject =>  return true; /* use your own filter */ ;

        // page configuration
        int iMaxItemPerPage = 2;
        int iCurrentPage = 0;
        int iStartIndex = iCurrentPage * iMaxItemPerPage;

        // déterminer les objects "de la page"
        int iCurrentIndex = 0;
        HashSet<object> hsObjectsInPage = new HashSet<object>();
        foreach (object oObject in cvCollectionView)
        
            // break if MaxItemCount is reached
            if (hsObjectsInPage.Count > iMaxItemPerPage)
                break;

            // add if StartIndex is reached
            if (iCurrentIndex >= iStartIndex)
                hsObjectsInPage.Add(oObject);

            // increment
            iCurrentIndex++;
        

        // refilter
        cvCollectionView.Filter = p_oObject =>
        
            return cvCollectionView.Contains(p_oObject) && hsObjectsInPage.Contains(p_oObject);
        ;

【讨论】:

这段代码究竟应该在 CollectionView 类的什么地方实现?您通常从 ViewModel 调用过滤器。否则此代码不可重用。

以上是关于自己的 CollectionView 用于分页、排序和过滤的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 panGestureRecognizer 启用 collectionView 分页

启用collectionview分页时将collection view滚动到索引

Swift - 使用核心数据和CollectionView进行分页

使用CollectionView做横向滑动分页效果:

Swift:按屏幕分页不适用于两列布局集合视图

在 swift collectionView 上遇到分页问题