! 제품 버전을 정확하게 입력해 주세요.
제품 버전이 정확하게 기재되어 있지 않은 경우,
최신 버전을 기준으로 안내 드리므로
더욱 빠르고 명확한 안내를 위해
제품 버전을 정확하게 입력해 주세요!

C# .NET Datagrid에서 UI 가상화가 작동하는 방식 > 블로그 & Tips

본문 바로가기

ComponentOne

블로그 & Tips

C# .NET Datagrid에서 UI 가상화가 작동하는 방식

페이지 정보

작성자 MESCIUS 작성일 2023-12-21 09:57 조회 114회 댓글 0건

본문

WPF 사용자 인터페이스는 시각적 트리에 UI 요소를 추가하여 생성됩니다.


WPF DataGrid 컨트롤은 수많은 UI 요소로 구성됩니다.


예를 들어, DataGrid의 각 셀에는 TextBlock 및 Border와 같은 두 개 이상의 기본 요소가 포함될 수 있습니다.


이제 DataGrid에 수천 개의 행이 표시되고, 많은 UI 요소가 필요하며 각 요소가 한정된 양의 메모리를 차지한다고 상상해 보세요.


이 블로그에서는 UI 가상화를 통해 이 문제를 해결하는 방법 및 WPF DataGrid 컨트롤을 위해 이를 구현하는 방법을 설명합니다.



UI 가상화란 무엇인가? 


UI 컨트롤이 많은 수의 항목을 표시해야 하는 경우, 메모리를 덜 소비하고 좋은 응용 프로그램 성능을 유지하기 위해 시각적 트리를 최적화해야 합니다.


일반적인 솔루션은 UI 가상화라고 하며, 사용자가 인터페이스를 스크롤하고 탐색함에 따라 항목이 생성되고 폐기됩니다.


이해해야 하는 공통적인 용어는 뷰포트(Viewport)입니다.


이 용어는 UI 요소 수를 최소화하면서도 UI를 원하는 상태로 유지하기 위한 컨트롤의 시각적 영역을 지칭합니다.

C# .NET 가상화


뷰포트 내 요소는 레이아웃 패스(Layout Pass) 중에 생성, 업데이트 또는 제거됩니다.


더 작은 컨트롤이나 정적 컨트롤에서는 모든 시각적 요소가 한 번에 생성되며, 이후에 컨트롤의 레이아웃을 호출하면 단순히 상위 요소가 전달된 레이아웃 치수에 따라 요소가 재배치됩니다.


이로 인해 레이아웃이 매우 가볍고 반응성이 높아지지만 UI 가상화 컨트롤에서는 요소 생성이 지연되고 레이아웃 전달에 위임됩니다.


이는 컨트롤의 치수를 알아야 해당 치수에 따라 표시할 수 있는 하위 요소를 생성할 수 있기 때문입니다.


하위 요소를 생성하고 레이아웃을 지정하는 것은 까다로운 작업일 수 있고 레이아웃 전달 과정에서 모든 것을 수행해야 하므로, 이러한 코드는 매우 빨라야 합니다.


그러지 않으면, 스크롤할 때 UI가 투박해집니다.

 

이 코드를 빠르게 만드는 작업은 컨트롤에 따라 크게 다릅니다.


하지만 시각적 요소를 재활용하고, 시각적 트리를 최대한 줄이고, 레이아웃 알고리즘 자체를 최적화하는 것과 같은 일부 일반적인 기법은 항상 유용합니다.



재활용을 통한 UI 가상화가 작동하는 방식 


listview, datagrids, treeviews 등 일련의 항목을 렌더링하는 UI 가상화 컨트롤에서는 한 항목이 보기 밖으로 나갈 때 해당 요소를 사용하여 새로 표시되는 요소를 렌더링할 수 있습니다.


이를 재활용(Recycling)이라고 합니다.


이러한 방법으로 요소를 생성하지 않고, 새로운 데이터 항목에 바인딩하기만 하면 시각적 요소의 UI가 보존됩니다.


따라서 요소를 제거하고 생성하는 과정을 건너뛰기 때문에 성능 측면에서 크게 절약이 됩니다.


메모리와 시간이 조금 절약될 뿐이지만, Datagrid가 클 경우 이러한 작은 절약이 더 중요해집니다.


가장 간단한 방법은 모든 요소를 재활용하고 모든 레이아웃 전달 과정에서 새로 표시되는 항목을 재활용된 요소에 바인딩하는 것이며 일부 항목이 이전 전달 과정에서 이미 배치되었는지 여부를 감지하도록 개선할 수 있습니다.


이러한 항목은 이미 바인딩되었으므로 위치만 다시 계산하면 됩니다.


시각적 요소의 생성 뿐만 아니라 항목을 시각적 요소에 바인딩하는 측면에서도 절약할 수 있습니다.

C# .NET 가상화



다양한 요소를 재활용하는 방법 


모든 요소가 동일한 템플릿이나 유형을 따른 경우에는 재활용이 간단합니다.


안에 텍스트가 있는 항목과 이미지 또는 체크박스가 있는 항목의 리스트 뷰처럼, 표시될 시각적 요소가 동일한 종류가 아닌 경우가 있습니다.


이 경우 재활용된 요소가 다른 항목에 유용하지 않기 때문에 재활용 알고리즘에 문제가 발생합니다.


시각적 트리의 부분을 다시 생성해야 하는 것은 좋은 방법이 아닙니다.


가장 효과적인 기법은 항목에 따라 필요한 시각적 요소의 종류를 감지하고 별도로 재활용하는 것입니다.


이러한 방법을 사용하면, 요소가 재활용된 후 시각적 요소만 필요하게 되며 시각적 트리는 변경되지 않습니다.



레이아웃 전달 최적화 


대부분의 플랫폼에서 레이아웃 패스는 측정과 정렬, 두 단계로 구성됩니다.


이 단계에서 코드를 적게 실행할수록 레이아웃 패스가 더 빨라집니다.


요소 측정은 광범위한 작업이며 최대한 피해야 합니다.


DataGrid에서는 일반적으로 텍스트 길이를 측정하고 셀을 조정하지 않습니다.

이는 비용이 많이 들며 일반적으로 각 셀의 크기가 동일하기 때문입니다.


하지만, 일부 다른 시나리오의 경우 위치를 결정하기 위해 요소 크기를 측정해야 하며 비용이 많은 작업을 실행해야 할 수 있습니다.


정렬 단계에서 주요 작업은 요소를 배치하는 것입니다.


그러므로, 신속하고 효율적으로 위치를 완료하는 것이 목표입니다.


이전 문서에서는 복잡하고 큰 레이아웃 위치를 신속하게 계산하는 데 적합한 데이터 구조에 대해 설명했습니다.


레이아웃을 더 가볍게 만드는 또 다른 방법은 모든 항목의 레이아웃을 줄이는 것입니다.


리스트뷰 항목 또는 데이터그리드 셀과 같이 안에 텍스트가 있는 더 넓은 요소를 사용하는 일반적인 시나리오를 고려해 보겠습니다.


이에 대한 자연스러운 솔루션은 Border 요소 내에 TextBlock 요소를 배치하는 것입니다.


하지만 이러한 UI 요소는 선과 텍스트 외에 더 많은 것을 표시하므로, 기능에 과부하가 추가됩니다.


예를 들어, TextBlock은 많은 일을 하는 매우 풍부한 요소이지만, 화면에 텍스트만 그려야 하는 경우 더 빠른 솔루션이 있습니다.


DrawText와 같은 원시 그래픽 그리기 방법을 사용한 2D 렌더링으로 텍스트를 더 빠르게 그리고, 장기적으로 성능을 향상할 수 있습니다.


WPF용 ComponentOne FlexGrid에서 Datagrid 셀을 신속하게 그리기 위해 이 접근 방법을 구현했습니다.


이전 블로그, 2D 셀 렌더링으로 WPF 데이터 그리드 성능을 향상하는 방법에서 이 기법에 대해 자세히 알아볼 수 있습니다.



렌더 스크롤링으로 레이아웃 전달 문제 해결 


UI 컨트롤이 스크롤되면 레이아웃 패스가 시작됩니다.


리스트뷰 또는 데이터그리드를 아래로 스크롤하면 레이아웃 전달이 너무 여러 번(픽셀이 변경될 때마다 한 번씩) 시작되므로, 측정 및 정렬 프로세스가 자주 수행되어 성능이 저하됩니다.


각 측정 프로세스에 대해 항목 오프셋을 계산하는 경우 더욱 복잡해집니다.


마우스 휠 스크롤과 같이 일부 시나리오의 경우에는 괜찮지만, 관성이 있는 드래그 동작의 경우 그렇지 않습니다.


렌더 스크롤링(Render Scrolling)이라고 하는 방법으로 이 문제를 극복할 수 있습니다.


각 레이아웃 패스의 결과는 GPU에 렌더링됩니다.


이후에는 불투명도, 크기 조정, 변환 등의 속성을 사용하여 계속해서 UI 요소의 모양을 정렬하고 수정할 수 있습니다.


이러한 속성은 크기 조정 또는 변환을 수행하는 경우에도 렌더링된 요소의 모양을 제외하고, 레이아웃에 영향을 미치지 않습니다.


해당 속성을 사용해 요소를 추가 이동하고 크기를 조정하여, 레이아웃 전달에 전혀 영향을 미치지 않고 원하는 결과를 달성할 수 있습니다.


그 결과 GPU에서 바로 작업이 수행되므로 스크롤링이 매우 빨라집니다.


아래 애니메이션은 표준 레이아웃 스크롤 업데이트와 렌더 스크롤링의 차이를 보여줍니다.


녹색 깜박임은 업데이트 빈도를 나타냅니다.


[레이아웃 스크롤링]

[렌더 스크롤링]

 


이 '렌더 스크롤링' 접근 방법을 사용하는 경우에도, 특정한 경우 레이아웃을 무효화(또는 업데이트)해야 합니다.  


그러지 않으면 빈 화면이 표시될 수 있습니다.


레이아웃을 무효화하는 속도는 표준 레이아웃 전달 기반 스크롤링을 사용하는 것보다 훨씬 느립니다.


스크롤하는 동안 빈 화면이 표시되지 않도록 하려면, 일부 추가 항목을 뷰포트 밖에 배치하여 화면에 표시되기 전에 미리 로드되도록 해야 합니다.


이는 렌더 스크롤링이 항상 일반 레이아웃 업데이트보다 더 빠르지만 해당 뷰포트 차이가 너무 크지 않아야 하므로 필수적입니다.


그러지 않으면 레이아웃에 영향을 미쳐, 더 많은 요소를 계산해야 합니다.



결론 


이 블로그에서는 여러 UI 가상화 솔루션을 처리하기 위한 팁과 기법을 설명했습니다.


Microsoft에서는 ItemsControls에서 재활용을 지원하며, C1FlexGrid와 같은 완전한 WPF datagrid를 사용하는 경우 구현에 대해 걱정하지 않아도 됩니다.


위에 언급된 모든 기능은 이미 내장 기능에 포함되어 있기 때문입니다.




지금 바로 ComponentOne을 다운로드하여 직접 테스트해보세요!

 
  • 페이스북으로 공유
  • 트위터로  공유
  • 링크 복사
  • 카카오톡으로 보내기

댓글목록

등록된 댓글이 없습니다.

메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기

태그1

메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기
이메일 : sales-kor@mescius.com | 전화 : 1670-0583 | 경기도 과천시 과천대로 7길 33, 디테크타워 B동 1107호 메시어스(주) 대표자 : 허경명 | 사업자등록번호 : 123-84-00981 | 통신판매업신고번호 : 2013-경기안양-00331 ⓒ 2024 MESCIUS inc. All rights reserved.