2017-02-21 51 views
0

我有一个很大的数据集,按照用户标准用ICollectionView过滤,我想从合格的结果中执行数据分页。一旦过滤数据,我如何过滤分页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; 
+0

我假设你是寻呼与此类似http://stackoverflow.com/questions/784726/how-can-i-paginate-a-wpf-datagrid,在这种情况下,您应该只需更改'this._innerList.Count'来计算通过过滤器的位置,则不需要堆叠意见 – MikeT

+0

看到下面的例子 – MikeT

+0

我在评估这个例子是否适合我的情况。非常感谢!我会给一些反馈! – arturn

回答

0

的例子从How can I paginate a WPF DataGrid?

和简单地改变条件要考虑到过滤

EG

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(); 
    } 
} 

演示 VM:

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; } 
} 

XAML:

<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> 

注意:此代码是不是生产代码只是一个例子来说明所需要的过程,它没有强大的

+0

属性'FilteredCollection'是每次我们访问它过滤整个集合,是这样吗? – arturn

+0

是的,你可以通过缓存结果来提高效率,只要确保清除缓存刷新 – MikeT

+0

它也值得注意的是,集合视图现在接受IEnumerable而不是ILsit – MikeT