2013-04-04 1 views
2

Я внедрил свой собственный CollectionView для привязки коллекции данных к DataGrid в WPF.Own CollectionView для подкачки, сортировки и фильтрации

Главной целью было разбиение на страницы, которое работает достаточно хорошо. Я написал следующий код C#:

public class SchemesCollectionView : CollectionView 
{ 
    private readonly IList<Scheme> innerList; 
    private readonly int itemsPerPage; 

    private int currentPage = 1; 

    public SchemesCollectionView(IList<Scheme> source, int itemsPerPage) 
     : base(source) 
    { 
     innerList = source; 
     this.itemsPerPage = itemsPerPage; 
    } 

    public override int Count 
    { 
     get { return itemsPerPage; } 
    } 

    public int CurrentPage 
    { 
     get { return currentPage; } 
     set 
     { 
      currentPage = value; 
      OnPropertyChanged(new PropertyChangedEventArgs("CurrentPage")); 
      OnPropertyChanged(new PropertyChangedEventArgs("FirstItemNumber")); 
      OnPropertyChanged(new PropertyChangedEventArgs("LastItemNumber")); 
     } 
    } 

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

    public int PageCount 
    { 
     get 
     { 
      return (this.innerList.Count() + this.itemsPerPage - 1) 
       /this.itemsPerPage; 
     } 
    } 

    public int LastItemNumber 
    { 
     get 
     { 
      var end = currentPage * itemsPerPage - 1; 
      end = (end > innerList.Count()) ? innerList.Count() : end; 

      return end + 1; 
     } 
    } 

    public int StartIndex 
    { 
     get { return (currentPage - 1) * itemsPerPage; } 
    } 

    public int FirstItemNumber 
    { 
     get { return ((currentPage - 1) * itemsPerPage) + 1; } 
    } 

    public override object GetItemAt(int index) 
    { 
     var offset = index % (ItemsPerPage); 

     var position = StartIndex + offset; 

     if (position >= innerList.Count) 
     { 
      position = innerList.Count - 1; 
     } 

     return innerList[position]; 
    } 

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

    public void MoveToPreviousPage() 
    { 
     if (CurrentPage > 1) 
     { 
      CurrentPage -= 1; 
     } 
     Refresh(); 
    } 

    public void MoveToFirstPage() 
    { 
     CurrentPage = 1; 
     Refresh(); 
    } 

    public void MoveToLastPage() 
    { 
     CurrentPage = PageCount; 
     Refresh(); 
    } 
} 

Как уже упоминалось, нумерация страниц работает очень хорошо. Но я не могу выполнить фильтрацию и сортировку. Когда я добавляю собственный фильтр к свойству Filter, он полностью игнорируется. То же самое с сортировкой. Я вижу стрелки в заголовках столбцов после того, как я щелкнул их, но различная сортировка не отражена в DataGrid.

Что мне здесь не хватает? Надеюсь, кто-то может помочь.

ответ

2

Как уже упоминалось, вы можете взять код из Silverlight и использовать его в WPF.

Paged Collection View in WPF

+0

спасибо. Источник выглядит хорошо. Я скопировал его в свой проект, но каждый раз, когда я хочу использовать разбивку на страницы (например, одна страница вперед), я получаю «Коллекция была изменена, операция перечисления не может выполняться». ошибка. Не знаю, почему и как я решаю эту проблему. – FDeitelhoff

0

Вот это решение для фильтрации и поискового вызова, используя только класс CollectionView.

Вам просто нужно установить текущий индекс страницы и максимальное количество элементов на странице в соответствии с вашими потребностями.

 // obtenir la CollectionView 
     ICollectionView cvCollectionView = CollectionViewSource.GetDefaultView(this.Suivis); 
     if (cvCollectionView == null) 
      return; 

     // filtrer ... exemple pour tests DI-2015-05105-0 
     cvCollectionView.Filter = p_oObject => { return true; /* use your own filter */ }; 

     // page configuration 
     int iMaxItemPerPage = 2; 
     int iCurrentPage = 0; 
     int iStartIndex = iCurrentPage * iMaxItemPerPage; 

     // déterminer les objects "de la page" 
     int iCurrentIndex = 0; 
     HashSet<object> hsObjectsInPage = new HashSet<object>(); 
     foreach (object oObject in cvCollectionView) 
     { 
      // break if MaxItemCount is reached 
      if (hsObjectsInPage.Count > iMaxItemPerPage) 
       break; 

      // add if StartIndex is reached 
      if (iCurrentIndex >= iStartIndex) 
       hsObjectsInPage.Add(oObject); 

      // increment 
      iCurrentIndex++; 
     } 

     // refilter 
     cvCollectionView.Filter = p_oObject => 
     { 
      return cvCollectionView.Contains(p_oObject) && hsObjectsInPage.Contains(p_oObject); 
     }; 

 Смежные вопросы

  • Нет связанных вопросов^_^