WPF용 FlexGrid에서 데이터 가상화를 적용하는 방법
페이지 정보
작성자 GrapeCity 작성일 2021-01-04 16:04 조회 5,404회 댓글 0건본문
첨부파일
관련링크
FlexGrid는 대용량 데이터 집합을 빠르게 로드할 수 있는 강력한 고성능 WPF DataGrid입니다.
FlexGrid가 대용량 데이터 집합 관련 작업에 탁월한 한 가지 이유는 데이터 가상화를 지원하기 때문입니다. 사용자가 스크롤하면서 요청 시 데이터 가상화를 통해 데이터를 로드할 수 있습니다.
데이터 가상화 기능은 C1DataCollection 라이브러리에서 구현됩니다.
본 문서에서는 FlexGrid for WPF를 사용해 가상 컬렉션을 구현하는 방법을 보여드립니다. 가상 컬렉션 표시 방법도 시연해 드리겠습니다.
데이터 가상화란 무엇인가
데이터 가상화는 대량의 데이터가 더 짧은 시간 내에 로드되게 함으로써 데이터를 효율적으로 처리할 수 있게 지원합니다.
데이터 가상화는 사용자가 스크롤하면서 요청 시 데이터를 청크로 로드하는 방식으로 작동하며, 증분 방식 로드라고도 합니다.
대부분의 시나리오에서 데이터는 다양한 원격 소스 시스템에서 가져옵니다.
데이터 소스는 데이터를 표시하는 데 필요한 시간에 영향을 미치고 네트워크 사용 시 고유 비용을 발생시킵니다.
이러한 문제를 해결하기 위해 데이터를 분할하여 청크 또는 페이지 단위로 클라이언트에 전송합니다.
데이터 가상화를 구현하는 방법
ComponentOne 관련 작업을 할 때 최신 데이터 컬렉션 라이브러리인 C1DataCollection을 사용할 수 있습니다.
이 라이브러리는 모든 DataGrid 또는 목록 컨트롤에 데이터 가상화를 제공합니다.
C1DataCollection 라이브러리는 기본 클래스인 C1VirtualDataCollection을 제공합니다. 이 클래스에는 컬렉션을 채울 항목을 반환하는 추상적인 GetPageAsync() 메서드가 있습니다. 가상 데이터 컬렉션은 데이터를 캐싱하여 여러 페이지가 한 번에 요청되는 것을 방지하는 일련의 매개 변수에 따라 페이지의 요청을 디스패치합니다.
다음은 C1VirtualDataCollection 기본 클래스의 샘플 확장입니다.
public class VirtualModeCollectionView : C1VirtualDataCollection<Customer> { public VirtualModeCollectionView() { PageSize = 50; } public int TotalCount { get; set; } = 250_000; protected override async Task<Tuple<int, IReadOnlyList<Customer>>> GetPageAsync(int pageIndex, int startingIndex, int count, IReadOnlyList<SortDescription> sortDescriptions = null, FilterExpression filterExpression = null, CancellationToken cancellationToken = default) { //await Task.Delay(500, cancellationToken);//Simulates network traffic. return new Tuple<int, IReadOnlyList<Customer>>(TotalCount, Enumerable.Range(startingIndex, count).Select(i => new Customer(i)).ToList()); } }
구성자에서 페이지 크기를 설정할 수 있습니다. 여기서 “페이지”라는 용어를 사용하기는 하지만 다음 및 이전 버튼으로 기본 페이징을 구현하는 것은 아닙니다.
기본적으로 페이징을 하기는 하지만 사용자가 항목의 목록을 위아래로 스크롤할 때 모두 발생합니다.
GetPageAsync 메서드는 페이지에서 항목을 반환하고, 그다음 페이지에서는 토큰을 반환합니다.
이 메서드는 pageIndex, startingIndex, count, sortDescriptions, filterExpression, 취소 토큰을 매개 변수로 사용합니다.
pageIndex는 요청 페이지의 인덱스이고, startingIndex는 반환된 항목이 삽입되는 인덱스이며, count는 반환될 항목의 개수입니다.
위 코드는 서버에서 데이터 가져오기를 시뮬레이션합니다.
샘플과 관련해서는 이 주제를 확인하십시오.
FlexGrid에 데이터 가상화 추가
FlexGrid를 이 가상 데이터 컬렉션으로 채우기 위해 ItemsSource를 VirtualModeCollectionView 인스턴스로 전달하는 C1CollectionView로 설정합니다.
C1CollectionView는 정렬, 필터링, 그룹화와 같은 일반적인 데이터 변환을 추가합니다.
private VirtualModeCollectionView _virtualCollection; public MainWindow() { InitializeComponent(); UpdateData(); } private void UpdateData() { try { _virtualCollection = new VirtualModeCollectionView() { Mode = C1.DataCollection.VirtualDataCollectionMode.Manual }; c1FlexGrid1.ItemsSource = new C1CollectionView(_virtualCollection); c1FlexGrid1.ScrollPositionChanged += C1FlexGrid1_ScrollPositionChanged; _virtualCollection.LoadAsync(c1FlexGrid1.ViewRange.Row, c1FlexGrid1.ViewRange.Row2); } catch(Exception e) { MessageBox.Show(e.Message); } } private void C1FlexGrid1_ScrollPositionChanged(object sender, EventArgs e) { _virtualCollection.LoadAsync(c1FlexGrid1.ViewRange.Row, c1FlexGrid1.ViewRange.Row2); }
가상 데이터 컬렉션에는 데이터 로드 방식, 즉, 자동 또는 수동을 결정하는 모드가 있습니다 자동의 경우 항목에 액세스할 때 데이터를 로드하지만 이를 지원하려면 UI 컨트롤이 필요합니다.
수동 모드를 이용하면 LoadAsync 메서드를 호출하여 데이터 가상화를 모든 UI 컨트롤과 함께 사용할 수 있습니다.
위 코드에서 보시는 바와 같이 FlexGrid는 수동 모드를 사용하고 있습니다.
FlexGrid가 수동 모드를 사용하는 이유는 FlexGrid의 .NET 4.5.2 버전이 새로운 C1DataCollection보다 비교적 더 오래되었기 때문입니다. 이 문서를 작성하는 시점에 FlexGrid는 자동 모드를 지원하도록 업데이트되지 않은 상태이지만, .NET 5 버전에서는 자동 모드를 지원할 것이므로 훨씬 더 적은 코드가 필요할 것입니다.
자동 모드에서 WPF용 FlexGrid과 MS DataGrid 컨트롤의 .NET 4.5.2 버전은 컬렉션을 반복하고, 그 결과 C1VirtualDataCollection 가상화가 중단됩니다.
이러한 경우에는 수동 모드를 사용해 ScrollChanged 이벤트를 처리함으로써 아래쪽으로 스크롤할 때 더 많은 페이지를 로드해야 합니다. 위 코드에서 ScrollChanged 이벤트가 호출되면 C1VirtualDataCollection의 LoadAsync 메서드를 사용해 새로운 뷰포트 범위의 다음 레코드가 비동기식으로 로드됩니다.
셀에서 미리 보기 텍스트 표시
데이터 가상화의 문제점 중 하나는 서버에서 데이터가 물리적으로 다운로드되는 것보다 더 빠르게 사용자가 스크롤할 수 있다는 것입니다.
이 경우 UI를 차단하는 대신 셀에서 “로드 중...”과 같은 미리 보기 텍스트를 표시하여 DataGrid가 빈 상태로 표시되지 않게 할 수 있습니다.
미리 보기 텍스트는 가상 컬렉션에서 sentinel 항목을 생성함으로써 구현할 수 있습니다.
public override Customer this[int index] { get { var item = base[index]; if (item != null) return item; return new Customer() { FirstName = "Loading...", LastName = "Loading...", Address = "Loading...", City = "Loading...", Email = "Loading..." }; } }
위 코드 예시 전체는 에서 다운로드하실 수 있습니다.
댓글목록
등록된 댓글이 없습니다.