我找到了这个代码来对一个集合进行分页。它完全适用于我需要的东西,但我希望能够在另一个线程中进行分页,因为如果每页的项目数量很大,那么界面会冻结片刻。
“RecalculateThePageItems”方法负责创建每个页面(创建集合时,删除记录时,页面更改时)。一些帮助?非常感谢你!
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace WPF.Utilidades
{
/// <summary>
/// This class represents a single Page collection, but have the entire items available inside
/// </summary>
public class PaginatedObservableCollection<T> : ObservableCollection<T>
{
#region Properties
private const int FistPage = 1;
private readonly List<T> _originalCollection;
#region Commands
public void ExecuteNextPage()
{
CurrentPage++;
OnPropertyChanged(new PropertyChangedEventArgs("ItemsFrom"));
OnPropertyChanged(new PropertyChangedEventArgs("ItemsTo"));
}
public bool CanExecuteNextPage()
{
return TotalPages > CurrentPage;
}
public void ExecutePreviousPage()
{
CurrentPage--;
OnPropertyChanged(new PropertyChangedEventArgs("ItemsFrom"));
OnPropertyChanged(new PropertyChangedEventArgs("ItemsTo"));
}
public bool CanExecutePreviousPage()
{
return CurrentPage > FistPage;
}
public void ExecuteFirstPage()
{
CurrentPage = FistPage;
OnPropertyChanged(new PropertyChangedEventArgs("ItemsFrom"));
OnPropertyChanged(new PropertyChangedEventArgs("ItemsTo"));
}
public bool CanExecuteFirstPage()
{
return TotalPages > 0 && CurrentPage != FistPage;
}
public void ExecuteLastPage()
{
CurrentPage = TotalPages;
OnPropertyChanged(new PropertyChangedEventArgs("ItemsFrom"));
OnPropertyChanged(new PropertyChangedEventArgs("ItemsTo"));
}
public bool CanExecuteLastPage()
{
return CurrentPage != TotalPages;
}
#endregion
private int _itemsPerPage;
private int ItemsPerPage
{
get { return _itemsPerPage; }
set
{
if (value > 0)
{
_itemsPerPage = value;
RecalculateItemsPerPage();
OnPropertyChanged(new PropertyChangedEventArgs("ItemsPerPage"));
}
}
}
private int _currentPage;
public int CurrentPage
{
get { return _currentPage; }
set
{
if (value > 0)
{
_currentPage = value;
RecalculateItemsPerPage();
OnPropertyChanged(new PropertyChangedEventArgs("CurrentPage"));
}
}
}
private int _totalPages;
public int TotalPages
{
get { return _totalPages; }
set
{
if (_totalPages != value)
{
if (value < _currentPage)
{
CurrentPage--;
}
_totalPages = value;
OnPropertyChanged(new PropertyChangedEventArgs("TotalPages"));
}
}
}
private int _totalItems;
public int TotalItems
{
get { return _originalCollection.Count; }
set
{
if (_totalItems != value)
{
_totalItems = value;
OnPropertyChanged(new PropertyChangedEventArgs("TotalItems"));
}
}
}
private int _itemsFrom;
public int ItemsFrom
{
get { return _originalCollection.Count > 0 ? (CurrentPage - 1) * ItemsPerPage + 1 : 0; }
set
{
if (_itemsFrom != value)
{
_itemsFrom = value;
OnPropertyChanged(new PropertyChangedEventArgs("ItemsFrom"));
}
}
}
private int _itemsTo;
public int ItemsTo
{
get { return ItemsFrom == 0 ? 0 : ItemsFrom + ItemsPerPage - 1 < TotalItems ? ItemsFrom + ItemsPerPage - 1 : TotalItems; }
set
{
if (_itemsTo != value)
{
_itemsTo = value;
OnPropertyChanged(new PropertyChangedEventArgs("ItemsTo"));
}
}
}
#endregion
#region Constructor
public PaginatedObservableCollection(IEnumerable<T> collection)
{
_originalCollection = new List<T>(collection);
_currentPage = 1;
_itemsPerPage = 10;
CalculateTotalPages();
RecalculateItemsPerPage();
}
public PaginatedObservableCollection(int itemsPerPage)
{
_itemsPerPage = itemsPerPage <= 0 ? 1 : itemsPerPage;
_originalCollection = new List<T>();
}
public PaginatedObservableCollection()
{
_originalCollection = new List<T>();
}
#endregion
#region Private
private void RecalculateItemsPerPage()
{
Clear();
var startIndex = _currentPage * _itemsPerPage - _itemsPerPage;
for (var i = startIndex; i < startIndex + _itemsPerPage; i++)
{
if (_originalCollection.Count > i)
{
base.InsertItem(i - startIndex, _originalCollection[i]);
}
}
}
private void CalculateTotalPages()
{
var itemCount = _originalCollection.Count;
var thisMod = itemCount % _itemsPerPage;
var thisDiv = itemCount / _itemsPerPage;
TotalPages = thisMod == 0 ? thisDiv : thisDiv + 1;
}
#endregion
#region Overrides
protected override void InsertItem(int index, T item)
{
var startIndex = _currentPage * _itemsPerPage;
var endIndex = startIndex + _itemsPerPage;
//Check if the Index is with in the current Page then add to the collection as bellow. And add to the originalCollection also
if ((index >= startIndex) && (index < endIndex))
{
base.InsertItem(index - startIndex, item);
if (Count > _itemsPerPage)
{
base.RemoveItem(endIndex);
}
}
if (index >= Count)
{
_originalCollection.Add(item);
}
else
{
_originalCollection.Insert(index, item);
}
}
protected override void RemoveItem(int index)
{
var startIndex = _currentPage * _itemsPerPage;
var endIndex = startIndex + _itemsPerPage;
//Check if the Index is with in the current Page range then remove from the collection as bellow. And remove from the originalCollection also
if ((index >= startIndex) && (index < endIndex))
{
RemoveAt(index - startIndex);
if (Count <= _itemsPerPage)
{
base.InsertItem(endIndex - 1, _originalCollection[index + 1]);
}
}
_originalCollection.RemoveAt(index + (_currentPage - FistPage) * _itemsPerPage);
CalculateTotalPages();
RecalculateItemsPerPage();
}
#endregion
}
}
创建一个集合(在viewModel中)
Articles =
await
TaskEx.Run(
() => new PaginatedObservableCollection<Article>(_articleService.GetList()));
删除元素(在viewModel中)
Articles.Remove(selectedArticle);
答案 0 :(得分:1)
更新您的Recalculate
方法以使用async
。
private async void RecalculateItemsPerPage()
{
await Task.Run(new Action(() =>
{
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
Clear();
var startIndex = _currentPage * _itemsPerPage - _itemsPerPage;
for (var i = startIndex; i < startIndex + _itemsPerPage; i++)
{
if (_originalCollection.Count > i)
{
base.InsertItem(i - startIndex, _originalCollection[i]);
}
}
}));
}));
}