I filter the collection CollectionViewSource . I use to break down the collection into pages (analogue of paging from the web). Actually a breakdown is carried out using

 CollectionViewSource.Filter = viewData_Filter. 

The event code is:

 void viewData_Filter(object sender, FilterEventArgs e) { int index = ((Product)e.Item).TmpId; if ((index >= ItemsPerPage * CurrentPage) && (index < ItemsPerPage * (CurrentPage + 1))) { e.Accepted = true; } else { e.Accepted = false; } } 

Here ItemsPerPage set when the application is initialized, CurrentPage and index - changes during program execution. Maybe there are ideas how to optimize, and then it takes too long to prepare the display?

    2 answers 2

    Sat down, thought. But everything turns out to be simple. Why did I climb into the jungle? Maybe I wanted to find a ready-made solution ... And it turned out to be redundant. Although it still needs to be checked, it may not all be in vain ... Actually, this is what occurred to me now about self-made paging: XAML:

     <Window x:Class="WpfApplication3.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="7*"></RowDefinition> <RowDefinition Height="1*"></RowDefinition> </Grid.RowDefinitions> <ListView Name="lvList" Grid.Row="0" ItemsSource="{Binding MyItems}"/> <TextBox Name="tbPage" Grid.Row="1" HorizontalAlignment="Left" Width="517" TextChanged="tbPage_TextChanged"/> </Grid> </Window> 

    Codebehind:

     public partial class MainWindow : Window { System.Collections.ObjectModel.ObservableCollection<string> collection; List<string> items; int pageLength = 50; public MainWindow() { InitializeComponent(); // инициализировали коллекцию items = new List<string>(); for (int i=0; i< 10000; i++) { items.Add("Строка номер " + i); } ChangePage(0); } public void ChangePage(int pageNum) { List<string> result = new List<string>(); result = new List<string>(items.Skip(pageNum * pageLength)); result = new List<string>(result.Take(pageLength)); collection = new System.Collections.ObjectModel.ObservableCollection<string>(result); lvList.ItemsSource = collection; } private void tbPage_TextChanged(object sender, TextChangedEventArgs e) { int page = 1; if (Int32.TryParse(tbPage.Text, out page)) { ChangePage(page); } } } 

    Only it is necessary to rewrite all the application logic, if you do this. What do you think?

    • Depends on. If you need padzhinatsiya in one place - a great solution. If in several - it will be possible to strangle because of copy-paste - Athari
    • This is an example. Naturally, in a combat version, all the logic needs to be packaged into a class and used at the object level. In general, over the weekend I will try to translate my application on these rails. I will write about the results. Maybe in the future someone will come in handy. And then I found a little information on this topic on the Internet. - Alexander Smirnov
    • Well, you are reinventing the CollectionView, essentially. You can do something, but why? - Athari
    • This option should work faster, because it does not shovel the entire collection, checking the condition of each item, but chooses a clearly desired range and returns it. I'll call QuickCollectionView: D - Alexander Smirnov
    • PagingCollectionView does the PagingCollectionView same thing. - Athari

    On a large StackOverflow, there is an example of padzhinaciya using its CollectionView class. I can not say which code will work faster, but it's worth a try.

     public class PagingCollectionView : CollectionView { private readonly IList _innerList; private readonly int _itemsPerPage; private int _currentPage = 1; public PagingCollectionView(IList innerList, int itemsPerPage) : base(innerList) { this._innerList = innerList; this._itemsPerPage = itemsPerPage; } public override int Count { get { if (this._currentPage < this.PageCount) // page 1..n-1 { return this._itemsPerPage; } else // page n { var itemsLeft = this._innerList.Count % 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 (this._innerList.Count + this._itemsPerPage - 1) / this._itemsPerPage; } } private int EndIndex { get { var end = this._currentPage * this._itemsPerPage - 1; return (end > this._innerList.Count) ? this._innerList.Count : end; } } private int StartIndex { get { return (this._currentPage - 1) * this._itemsPerPage; } } public override object GetItemAt(int index) { var offset = index % (this._itemsPerPage); return this._innerList[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(); } } 

    The full sample code and description can be found in the question " How can I paginate a WPF DataGrid? "

    • I took the code from the article by reference, tested it with a collection of 1000, 10000 and 100000 elements. In the specified code, I did not notice a drop in speed from an increase in the number of elements. But it still does not switch instantly. That is, there is a tangible delay ... And yet thanks, you can try to tie this approach to my program. Maybe that will change. Maybe someone else has options? - Alexander Smirnov
    • @AlexanderSmirnov Perhaps the bottleneck is not where you are looking. Try to leave dummies from the data templates and see if the problem is in the case. - Athari