2016-11-30 3 views
0

このコードでコレクションにページを設定しました。私が必要とするものは完璧に動作しますが、ページごとの項目数が多い場合はインターフェイスが一瞬停止するため、別のスレッドでページを設定できるようにしたいと考えています。カスタムページネック

"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 

    } 

} 

asyncを使用するようにRecalculate方法を更新し

Articles.Remove(selectedArticle); 

答えて

1

(ViewModelにで)要素を削除する(ViewModelにでは)

Articles = 
      await 
       TaskEx.Run(
        () => new PaginatedObservableCollection<Article>(_articleService.GetList())); 

をコレクションを作成します。

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]); 
       } 
      } 
     })); 
    })); 
} 
+0

ヘルプのためのThx!私は "使用" "Application.Current.Dispatcher.InvokeAsync"を含んでいる "問題"を持っているイムネット4.0を使用しています。 – avechuche

+0

@avechuche更新を参照してください。 'BeginInvoke'への変更に注意してください。 –

+0

もう一度おねがいします。私は既にそれを試しましたが、それはうまくいきません。これはBeginInvokeを使用するときのエラーです 'DispatcherOperation'に 'GetAwaiter'の定義が含まれておらず、 'AwaitExtensions.GetAwaiter(Task)'拡張メソッドの最善のオーバーヘッドが 'Task'が必要です – avechuche