C# 过滤数据后,如何对ICollectionView进行分页过滤?

C# 过滤数据后,如何对ICollectionView进行分页过滤?,c#,wpf,mvvm,data-binding,C#,Wpf,Mvvm,Data Binding,我有一个大的数据集,通过ICollectionView的用户标准进行过滤,我想从合格的结果执行数据分页 我想我需要ICollectionView一个用于过滤数据,另一个用于分页。这条路对吗 问题是ICollectionView。源不能是其他ICollectionView。 我尝试过其他一些选择,但没有成功 IEnumerable<foo> data; ICollectionView MyDataFilter; ... this.MyDataFilter = CollectionVie

我有一个大的数据集,通过ICollectionView的用户标准进行过滤,我想从合格的结果执行数据分页

我想我需要ICollectionView一个用于过滤数据,另一个用于分页。这条路对吗

问题是ICollectionView。源不能是其他ICollectionView。 我尝试过其他一些选择,但没有成功

IEnumerable<foo> data;
ICollectionView MyDataFilter;
...
this.MyDataFilter = CollectionViewSource.GetDefaultView(data);

System.Diagnostics.Debug.Assert(this.MyDataFilter.CanFilter);
this.MyDataFilter.Filter = DataViewFilter;

PaginationView = CollectionViewSource.GetDefaultView(this.MyDataFilter);
this.PaginationView.Filter = PaginationViewFilter;
IEnumerable数据;
ICollectionView MyDataFilter;
...
this.MyDataFilter=CollectionViewSource.GetDefaultView(数据);
System.Diagnostics.Debug.Assert(this.MyDataFilter.CanFilter);
this.MyDataFilter.Filter=DataViewFilter;
PaginationView=CollectionViewSource.GetDefaultView(this.MyDataFilter);
this.PaginationView.Filter=PaginationViewFilter;
使用中的示例

并简单地更改标准以考虑过滤

乙二醇

XAML:



注意:此代码不是生产代码,只是显示所需流程的一个示例,它不是健壮的

我假设您的分页与此类似,在这种情况下,您只需更改
this.\u innerList.Count
以计数通过过滤器的位置,然后,您不需要堆叠视图。请参阅下面的示例,我正在评估此示例是否适合我的情况。谢谢!我会给你一些反馈!您需要自己改进代码,例如,如果您在第10页更改了过滤器,因此只有5页示例将崩溃,我知道我必须进行更改,但现在我只评估解决问题的正确方法。.属性“FilteredCollection”在每次访问时都会过滤整个集合,是这样吗?是的,您可以通过缓存结果来提高效率,只需确保在刷新时清除缓存。另外值得注意的是,集合视图现在接受IEnumerable而不是ILsitI。如果您对上面编写的代码进行了任何更改,则可能就是源代码请参见
public class PagingCollectionView : CollectionView
{
    private readonly int _itemsPerPage;

    private int _currentPage = 1;

    public PagingCollectionView(IEnumerable innerList, int itemsPerPage)
        : base(innerList)
    {
        this._itemsPerPage = itemsPerPage;
    }

    public int FilteredCount
    {
        get {return FilteredCollection.Count(); }
    }

    private IEnumerable<object> FilteredCollection => this.SourceCollection.OfType<object>().Where(o=>Filter(o));
    public override int Count
    {
        get
        {
            if (FilteredCount == 0) return 0;
            if (this._currentPage < this.PageCount) // page 1..n-1
            {
                return this._itemsPerPage;
            }
            else // page n
            {
                var itemsLeft = FilteredCount % this._itemsPerPage;
                if (0 == itemsLeft)
                {
                    return this._itemsPerPage; // exactly itemsPerPage left
                }
                else
                {
                    // return the remaining items
                    return itemsLeft;
                }
            }
        }
    }

    public int CurrentPage
    {
        get { return this._currentPage; }
        set
        {
            this._currentPage = value;
            this.OnPropertyChanged(new PropertyChangedEventArgs("CurrentPage"));
        }
    }

    public int ItemsPerPage { get { return this._itemsPerPage; } }

    public int PageCount
    {
        get
        {
            return (FilteredCount + this._itemsPerPage - 1)
                / this._itemsPerPage;
        }
    }

    private int EndIndex
    {
        get
        {
            var end = this._currentPage * this._itemsPerPage - 1;
            return (end > FilteredCount) ? FilteredCount : end;
        }
    }

    private int StartIndex
    {
        get { return (this._currentPage - 1) * this._itemsPerPage; }
    }

    public override object GetItemAt(int index)
    {
        var offset = index % (this._itemsPerPage);
        return this.FilteredCollection.ElementAt(this.StartIndex + offset);
    }

    public void MoveToNextPage()
    {
        if (this._currentPage < this.PageCount)
        {
            this.CurrentPage += 1;
        }
        this.Refresh();
    }

    public void MoveToPreviousPage()
    {
        if (this._currentPage > 1)
        {
            this.CurrentPage -= 1;
        }
        this.Refresh();
    }
}   
public class VM:BindableBase
{
    public VM()
    {
        PagingCollectionView = new PagingCollectionView(
            Enumerable.Range(300, 1000).Select(i => i.ToString("X")),
            5);
        PagingCollectionView.Filter = (o) => string.IsNullOrWhiteSpace(Filter) || o.ToString().StartsWith(Filter);

        Next = new DelegateCommand(PagingCollectionView.MoveToNextPage);
        Previous = new DelegateCommand(PagingCollectionView.MoveToPreviousPage );
    }

    private string _Filter;

    public string Filter
    {
        get { return _Filter; }
        set {
            if(SetProperty(ref _Filter, value))
                PagingCollectionView.Refresh();
        }
    }

    public PagingCollectionView PagingCollectionView { get; set; }

    public DelegateCommand Next { get; set; }
    public DelegateCommand Previous { get; set; }
}
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:VM x:Name="vm" />
    </Window.DataContext>

    <DockPanel >
        <TextBox DockPanel.Dock="Top" Text="{Binding Filter}"/>
        <Button DockPanel.Dock="Left" Content="&lt;" Command="{Binding Previous}"  />
        <Button DockPanel.Dock="Right" Content="&gt;" Command="{Binding Next}"/>
        <ListView ItemsSource="{Binding PagingCollectionView}"/>

    </DockPanel>
</Window>