2D 셀 렌더링으로 WPF 데이터 그리드 성능을 향상하는 방법
페이지 정보
작성자 GrapeCity 작성일 2023-06-26 16:14 조회 408회 댓글 0건본문
관련링크
DrawString이나 DrawLine 같은 그래픽 드로잉 API를 사용하면 사용자 정의 셀에 프레임워크 요소를 사용하는 것보다 로딩 및 스크롤 성능을 최대 37%까지 개선할 수 있습니다.
이번 스터디에서는 XAML FlexGrid에서의 사용자 정의 셀 생성을 위한 다양한 기술을 설명합니다. 또, 새로운 2D 드로잉 방식을 사용하는 예시를 선보이고, 새로운 성능 이점을 공유하려고 합니다.
FlexGrid 사용자 정의 셀 렌더링 기술
XAML 플랫폼용 FlexGrid에서 셀을 사용자 정의하는 표준적인 접근 방식은 GridCellFactory(C#) 또는 CellTemplate(XAML)을 사용하는 것입니다. CellTemplate 속성을 사용하면 XAML 데이터 템플릿이 셀의 콘텐츠를 나타낼 수 있습니다. (게이지 컴포넌트와 같은) 특정 UI 컨트롤로 셀의 콘텐츠를 사용자 정의해야 하는 일부 경우에는 이 방법도 여전히 유용합니다. 하지만 일반 텍스트 및 도형을 표시하는 것과 같은 일반적인 경우에는 2D 렌더링 API로 셀 콘텐츠를 그리면 성능이 개선됩니다.
기본적으로 DrawString 메서드를 100 번 호출하는 것이 TextBlock을 100 개 렌더링하는 것보다 효율적입니다.
드로잉 API(System.Drawing)에 액세스하려면 GridCellFactory를 사용하여 C# 코드에 액세스해야 합니다. GridCellFactory를 사용하면 GetCellContentType, CreateCellContent, BindCellContent, UnbindCellContent 메서드를 재정의하여 셀 콘텐츠를 사용자 정의할 수 있습니다. 이렇게 하면 TextBlock과 같은 UI 프레임워크 요소로 셀을 렌더링할 수 있고, 렌더링 API를 사용할 수도 있습니다.
그 방법을 설명하기 위해 FlexGrid를 사용하여 틱택토 데모를 구현하겠습니다.
2D 렌더링 API로 셀을 렌더링하는 예제
첫 번째 단계는 사용자 정의 Cell Factory를 만들고 사용자 정의 셀을 활성화하는 것입니다. 이전에 개발된 셀 Cell Factory에 영향을 주는 수정을 피하기 위해, 사용자 정의 셀은 기본적으로 비활성화되어 있습니다.
public class MyCellFactory : GridCellFactory { public MyCellFactory() { AllowCustomCells = true; } }
그런 다음 메서드 GetCellKind, CreateCell, BindCell, UnbindCell을 재정의하여 원하는 셀 콘텐츠를 구현합니다. 이러한 메서드는 위에서 셀 콘텐츠를 만들기 위해 사용한 메서드와 유사합니다. 셀은 재사용되고 재활용되며, 재활용 알고리즘이 올바르게 작동하려면 사용자 정의 중인 셀의 종류를 지정해야 합니다.
편의상 아래 코드의 모든 셀은 같은 종류라고 가정하겠습니다.
public override object GetCellKind(GridCellType cellType, GridCellRange range) { return typeof(MyCustomCell); } public override GridCellView CreateCell(GridCellType cellType, GridCellRange range, object cellKind) { return new MyCustomCell(); } public override void BindCell(GridCellType cellType, GridCellRange range, GridCellView cell) { (cell as MyCustomCell).IsCross = isCross;//Sets the value to determine whether the cell shows a cross of a circle } public override void UnbindCell(GridCellType cellType, GridCellRange range, GridCellView cell) { }
MyCustomCell 클래스가 사용자 정의 그리기를 구현할 것입니다. WPF에서는 OnRender 메서드를 재정의하여 그리기를 수행할 수 있습니다. 또한 GridCellView에서 제공하는 OnRenderBackground를 재정의하여 테두리 그리기를 베이스 클래스가 수행하기 때문에 우리가 처리할 필요는 없습니다. 이 재정의 안에서 DrawLine 또는 DrawEllipse 메서드를 사용하여 원하는 틱택토 기호를 그립니다.
public class MyCustomCell : GridCellView { private bool _isCross; public bool IsCross { get => _isCross; set { _isCross = value; InvalidateVisual(); } } protected override void OnRenderBackground(DrawingContext drawingContext, Rect backgroundArea) { base.OnRenderBackground(drawingContext, backgroundArea); backgroundArea.Inflate(-8, -8);//Adds some padding if (IsCross) { drawingContext.DrawLine(new Pen(Foreground, 4), backgroundArea.TopLeft, backgroundArea.BottomRight); drawingContext.DrawLine(new Pen(Foreground, 4), backgroundArea.BottomLeft, backgroundArea.TopRight); } else { drawingContext.DrawEllipse(null, new Pen(Foreground, 4), new Point(backgroundArea.Left + backgroundArea.Width / 2, backgroundArea.Top + backgroundArea.Height / 2), backgroundArea.Width / 2, backgroundArea.Height / 2); } } }
다음으로 XAML에서 Cell Factory를 정의하는 방법을 보여드리겠습니다.
여기서는 3 개의 행과 3 개의 열이 있는 FlexGrid를 정의하여 틱택토 게임판을 시뮬레이션했습니다.
<c1:FlexGrid AutoGenerateColumns="False" DefaultColumnWidth="100" DefaultRowHeight="100" GridLinesVisibility="All" HeadersVisibility="None" SelectionMode="None" IsReadOnly="True"> <c1:FlexGrid.Rows> <c1:GridRow /> <c1:GridRow /> <c1:GridRow /> </c1:FlexGrid.Rows> <c1:FlexGrid.Columns> <c1:GridColumn /> <c1:GridColumn /> <c1:GridColumn /> </c1:FlexGrid.Columns> <c1:FlexGrid.CellFactory> <local:MyCustomCellFactory /> </c1:FlexGrid.CellFactory> </c1:FlexGrid>
성능 개선 살펴보기
테스트 결과 이미지 또는 프레임워크 요소 셀과 같은 대안에 비해 DrawLine 메서드를 사용했을 때 최대 37%의 성능 개선이 이루어졌습니다. 특히, 보유한 데이터의 행이 아무리 많아도 로딩 시간이 줄어들고 스크롤 속도가 빨라지는 성능 개선이 관찰되었습니다.
로딩 시간 | 스크롤 | |
---|---|---|
WPF | 34% 더 빠름 | 37% 더 빠름 |
Android | 34% 더 빠름 | 36% 더 빠름 |
iOS | 32% 더 빠름 | 36% 더 빠름 |
지금 바로 ComponentOne을 다운로드하여 직접 테스트해 보세요!
댓글목록
등록된 댓글이 없습니다.