Custom:DataGrid에
특정 정보 리스트를 ItemsSource=“{Binding Path=DataList}” 담아 화면에 뿌려주는데
많으면 5천줄이 넘어갈때가있습니다.
문제는 같은 화면에있는 콤보박스를 클릭하는순간 버퍼링이 생기는 현상입니다…
이게 DataGrid에 row수가 많을때만 이러는거같은데… 고민이네요…
Custom:DataGrid에
특정 정보 리스트를 ItemsSource=“{Binding Path=DataList}” 담아 화면에 뿌려주는데
많으면 5천줄이 넘어갈때가있습니다.
문제는 같은 화면에있는 콤보박스를 클릭하는순간 버퍼링이 생기는 현상입니다…
이게 DataGrid에 row수가 많을때만 이러는거같은데… 고민이네요…
이 글 첫번째 댓글을 참고해 보시겠어요?
많은 데이터를 화면에 렌더링 할때
한꺼번에 화면에 그려줄때엔 버벅 거리는 것이 당연한 현상 입니다.
이때 처리할 수 있는것이 UI가상화 처리 입니다.
즉 화면에 노출되는 스크롤 ViewPort영역에만 UI를 렌더링 하고 그 외 영역은 렌더링 하지 않는 처리 입니다.
WPF에서 가상화 처리를 지원해주는 컨트롤은 VirtualizingStackPanel 입니다.
DataGrid 또는 ListView의 ItemPanel을 스타일을 통해
VirtualizingStackPanel로 사용하도록 하고 몇가지 옵션을 주면 기본적인 UI가상화 처리가 가능합니다.
참고
VirtualizingStackPanel 클래스 (System.Windows.Controls) | Microsoft Learn
컨트롤 성능 최적화 - WPF .NET Framework | Microsoft Learn
System.Windows.Controls.VirtualizingPanel
System.Windows.Controls.Primitives.IScrollInfo
위 클래스를 상속받아 UI가상화 처리를 구현하실 수 있습니다.
댓글 감사합니다 알려주신 부분 적용해봤습니다.
하지만 콤보박스를 클릭할때의 반응은 그대로네요…
이게 1~2초정도면 과감하게 조금 버벅거리네요 라고 넘길테지만… 10초가 넘어가서…
무슨이유인지 콤보박스 클릭하는순간 저러더군요…
처음딱한번만 저런현상이 생기는데 도통 알수가없네요…
콤보박스에 바인딩 처리 되는 데이터가 많은건가요? 그렇다면 콤보박스도 가상화 처리가 필요하구요
콤보박스가 최초 데이터 바인딩 될때 관련해서 데이터 Load처리나 그 외 딜레이될만한 코드가 있는지 살펴 보셔야 합니다.
콤보박스는 클릭시 콤보박스 Popup이 표시 되면서 부터 바인딩 한 데이터가 load 됩니다.
아니요 콤보박스는 3줄입니다 코드값인데 1,2,3 이렇게 콤보박스에 바인딩합니다.
바인딩은 화면 띄울때 바인딩하구요
Binding 시 IsAsync 옵션을 True로 설정해보시는 것도 시도해보세요~
적용했었는데 datalist로드할때제외하고는 효과가없었습니다
대체 콤보박스를 클릭하는데 왜 화면전체가 버퍼링이걸리는지 이해할수가없네요… ㅠㅠ
콤보박스에 해당하는 속성을 어떻게 바인딩하고 계신가요?
혹은 체크했을 때 이벤트(또는 커맨드) 로직이 궁금하네요.
단순 bool 형식의 속성갮을 바꾸는데 몇 천 라인의 처음부터 탐색하는 것 일수도 있습니다.
Visual Studio 라이브 시각적 트리
를 이용해 문제를 확인해보실 수 있지 않을까 싶습니다. 예상하기로 Visual Tree의 UIElement 갯수가 상당히 많을것으로 보여집니다.
<ComboBox Grid.Row="1" Grid.Column="5" Margin="1,3,1,3" FontSize="15"
DisplayMemberPath="CodeNm" SelectedValuePath="CodeId"
ItemsSource="{Binding Path=CmbBindCodeData, Mode=OneWay}"
SelectedItem="{Binding Path=CmbBindCodeDataSelected}">
</ComboBox>
private ObservableCollection<CodeVO> cmbBindCodeData;
public ObservableCollection<CodeVO> CmbBindCodeData
{
get
{
cmbBindCodeData = new ObservableCollection<CodeVO>();
cmbBindCodeData.Add(new CodeVO { CodeNm = "전체", CodeId = "2" });
cmbBindCodeData.Add(new CodeVO { CodeNm = "내부", CodeId = "0" });
cmbBindCodeData.Add(new CodeVO { CodeNm = "외부", CodeId = "1" });
return cmbBindCodeData;
}
set
{
cmbBindCodeData = value;
base.RaisePropertyChanged("CmbBindCodeData");
}
}
private CodeVO cmbBindCodeDataSelected;
public CodeVO CmbBindCodeDataSelected
{
get { return cmbBindCodeDataSelected; }
set
{
cmbBindCodeDataSelected = value;
base.RaisePropertyChanged("CmbBindCodeDataSelected");
}
}
값을 바인딩하는데 이부분은 해당 콤보박스가있는 화면이 load 될때 바인딩합니다.
string CodeId = CmbBindCodeDataSelected.CodeId;
적용합니다…
화면이 느린거랑은 연관이 없을거 같긴한데.,
바인딩 속성 코드가 이상한거 같은데
get에서 매번 ObservableCollection을 생성해서 반환해주네요?
때문에 set의 의미가 없구요
그리고 xaml에서 DisplayMemberPath / SelectedValuePath 는 오타이신가요?
SCodeNm, SCodeId 가 아닌지…
제가 의심되는 부분은 DataGrid가 가상화 처리가 안되어 수많은 UIElement가 존재해 바인딩 반응이 느려지는게 아닌가 하는데요, @HKLee 님 가능하시면 실행되는 재현코드를 첨부해주시면 답변에 큰 도움이 될 것 같습니다.
네 오타입니다 옮겨쓰다보니 저래됫네요 ㄷㄷ
위 작성자분의 댓글에서 ‘알려주신 부분 적용해봤습니다.’
로 댓글이 있어서 가상화 처리가 잘 되어 있는 상태로 간주 했었는데
디모이님 말씀 처럼 가상화 처리가 제대로 되어 있지 않은 상태라면
DataGrid컨텐츠 자체에 많은 Element가 있어서 DataGrid자체가 느린(하위 비주얼 트리 모두)걸 수 도 있겠네요