본문 바로가기

Development/WPF

ListBox(ListView) DeferredScrolling Preview

Introduction

ListBox나 Listview와 같이 목록형으로 데이터를 출력하는 컨트롤에서 많은 양의 데이터를 출력할경우, 스크롤 바를 조작할때 스크롤 속도가 매우 느려지는 현상을 발생합니다. 속도가 느려지는 가장큰 원인은 스크롤하는 도중에 매번 화면에 출력될 View가 업데이트되면서 퍼포먼스에 영향을 주게 되는것인데, 이를 해결하기 위한 간단한 방법으로 ScrollViewer의 IsDeferredScrollingEnabled 속성을 이용해 스크롤이 모두 끝났을때 View를 갱신하는 방법이 있습니다.

하지만 IsDeferredScrollingEnabled을 사용 할 경우 스크롤 동작이 완료될때까지 뷰가 갱신되지 않기때문에 디테일한 탐색이 불가능하기 때문에 오히려 더 불편한 상황이 발생 할 수도 있습니다. 이번시간에는 IsDeferredScrollingEnabled를 사용하여 스크롤할 때 View 전체가 갱신되지는 않지만 Thumb가 위치 한 데이터를 미리보기 형태로 제공함으로서 효과적인 탐색이 가능하도록 하는 방법에 대해 소개합니다. 아래는 이번시간에 구현할 결과물 영상입니다.

Create Scrolling Preview Helper

위 동영상과 같은 내용을 구현하기 위해 가장 먼저 확인 해 봐야 할 것이 DefferedScrolling을 이용했을 때 ScrollBar의 변경상태를 확인하는 방법입니다. ScrollViewer에서 기본적으로 제공되는 ScrollChanged는 DefferedScrolling을 이용할 경우 마지막에만 이벤트가 호출되기 때문에 정확한 위치를 계산할 수 없습니다.

WPF에서는 DefferedScrolling을 제어할 수 있도록 ScrollBar에 DeferScrollToVerticalOffsetCommand를 제공하고 있습니다. 이 Command는 ScrollViewer가 DefferedScrolling를 사용해 스크롤을 조작할 때 호출되는 Command로 CommandParameter를 통해 현재 Thumb의 위치를 가져올 수 있습니다.

ScrollViewer를 사용하는 Selector 컨트롤에서 미리보기가 가능하도록 하기 위해서 아래와 같이 Attached Dependency Property를 정의하고 ScrollViewer에 CommandBinding을 추가해줍니다.

속성값을 DataTemplate으로 받는 이유는 사용자가 임의로 미리보기로 출력될 데이터의 모양을 수정할 수 있도록 하기 위해서입니다. 그리고 아래와 같이 Command가 발생했을때의 처리를 해줍니다.


마지막으로 Thumb의 위치를 통해 계산된 Item Index에 해당하는 아이템을 Thumb옆에 Popup으로 출력하면 완성 할 수 있습니다.


아래는 이번시간에 구현한 전체 소스코드이며 궁금하신점이나 문의사항은 이메일이나 댓글로 남겨주시면 답변드리도록 하겠습니다. 아래소스코드는 VisualStudio2010버전에서 제작되었습니다.