2012-09-03 4 views
10

CodePlex의 아이디어와 Bea Stollnitz의 블로그 및 Vincent Da Ven Berge의 논문 (동일한 링크)을 사용하여 데이터 가상화 솔루션을 구현했습니다. 그러나 나는 다른 방법이 필요했기 때문에 내 자신의 솔루션을 작성하기로 결정했습니다.DataGrid 행 요청 패턴 (데이터 가상화 포함)

이 해결책으로 약 백만 행을 표시하려면 DataGrid을 사용하고 있습니다. UI 가상화도 사용하고 있습니다. 내 솔루션은 가능하지만 특정 상황에서 DataGrid이 소스로부터 데이터를 요청하는 방식에 이상한 동작이 발생합니다.

해결책에 대해

나는 모든 과중한 작업을 수행하는 목록을 작성했다. VirtualList<T>.이라는 일반 클래스입니다. ICollectionViewFactory 인터페이스를 구현하므로 콜렉션 뷰 생성 메커니즘은 VirtualListCollectionView<T> 인스턴스를 작성하여이를 래핑 할 수 있습니다. 이 클래스는 ListCollectionView에서 상속됩니다. 나는 내 자신의 ICollectionView 구현을 작성하기위한 제안을 따르지 않았다. 상속은 잘 작동하는 것 같습니다.

VirtualList<T>은 전체 데이터를 페이지로 분할합니다. 총 항목 수를 가져오고 DataGrid이 목록 인덱서를 통해 행을 요청할 때마다 적절한 페이지를로드하거나 캐시에서이를 반환합니다. 페이지는 내부에서 재활용되며 DispatcherTimer은 유휴 시간에 사용되지 않은 페이지를 처리합니다.

데이터 요청 패턴 VirtualList<T>IList (비 제네릭)을 구현해야

  • 내가 배운 가장 먼저하는 일. 그렇지 않으면 ItemsControl은이를 IEnumerable으로 처리하고 모든 행을 쿼리/열거합니다. DataGrid은 유형이 안전하지 않으므로 IList<T> 인터페이스를 사용할 수 없으므로 논리적입니다.

  • 인덱스가 0 인 행은 종종 DataGrid에 의해 요청됩니다. 시각적 항목 측정 (호출 스택에 따라)에 사용되는 것 같습니다. 그래서, 나는 이것을 단순히 캐시합니다.

  • DataGrid 내부의 캐싱 메커니즘은 예측 가능한 패턴을 사용하여 표시된 행을 쿼리합니다. 먼저 보이는 행을 위에서 아래로 (모든 행에 대해 두 번) 요청한 다음 내림차순으로 보이는 영역 (첫 번째 보이는 행 포함) 앞에 몇 행을 조회합니다 (표시 영역의 크기에 따라 다름) 아래에서 위로 순서대로. 그 후 그것은 보이는 행 (마지막으로 보이는 행 포함)을 위에서 아래로 동일한 양의 행을 요청합니다.

    보이는 행 인덱스가 4,5,6 인 경우. 데이터 요청은 4,4,5,5,6,6,4,3,2,1,6,7,8,9가됩니다.

    내 페이지 크기가 올바르게 설정되어 있으면 현재 및 이전에로드 된 페이지에서 이러한 모든 요청을 처리 할 수 ​​있습니다.

  • CanSelectMultipleItemsTrue와 사용자가, 시프트 버튼 또는 마우스 드래그를 이용하여 여러 항목을 선택하는 DataGrid 선택 영역의 끝리스트의 처음부터 모든 행을 열거하면. 이 열거 형은 이 구현되었는지 여부에 관계없이 IEnumerable 인터페이스를 통해 발생합니다.

  • 선택한 행이 보이지 않고 현재 보이는 영역이 선택한 행에서 "멀리"있는 경우 DataGrid에서 선택한 행부터 보이는 영역의 끝까지 모든 항목을 요청하기 시작하는 경우가 있습니다. 사이에있는 모든 행을 포함하여 보이지 않습니다. 나는이 행동의 정확한 패턴을 이해할 수 없었다. 어쩌면 내 구현이 그 이유입니다.

내 질문에

    내가 궁금
  • , 왜 가시가 될 때 그 행이 다시 요청되기 때문에 비 가시 행에 대한 DataGrid 요청?

  • 모든 행을 두 번 또는 세 번 요청해야하는 이유는 무엇입니까?

  • DataGrid가 복수 항목 선택을 해제하는 것을 제외하고 IEnumerable을 사용하지 않도록 만드는 방법을 알려줄 사람이 있습니까?

답변

5

적어도 VirtualList를 속이는 방법을 찾았습니다. 당신은 그것을 here 읽을 수 있습니다.

다른 솔루션 (내 것보다 낫다)을 발견 한 경우 알려주십시오!

+0

예, 실제로 비슷한 결과를 얻었습니다. 이미로드 된 항목을 모두 반환합니다. 그 이후로 문제를 일으키지 않았다. 감사 –