나는 한 ItemsControl
하지만, 내가 가상화하고자하는 데이터의 목록을 포함 VirtualizingStackPanel.IsVirtualizing="True"
와 함께 작동하지 않습니다 ItemsControl
.
이것이 정말로 사실입니까 아니면 내가 알지 못하는 다른 방법이 있습니까?
테스트를 위해 다음 코드 블록을 사용했습니다.
<ItemsControl ItemsSource="{Binding Path=AccountViews.Tables[0]}"
VirtualizingStackPanel.IsVirtualizing="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Initialized="TextBlock_Initialized"
Margin="5,50,5,50" Text="{Binding Path=Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
나는를 변경하는 경우 ItemsControl
A를 ListBox
, 나는 것을 볼 수 있습니다 Initialized
이벤트는 시간의 소수를 실행하는 그러나로, (나는 몇 레코드를 가야 단지, 그래서 거대한 마진은) ItemsControl
모든 항목이 초기화됩니다.
ItemsControlPanelTemplate
를 a로 설정하려고했지만 VirtualizingStackPanel
도움이되지 않는 것 같습니다.
답변
실제로 ItemsPanelTemplate
사용 하는 것보다 훨씬 더 많은 것이 있습니다 VirtualizingStackPanel
. 기본 ControlTemplate
에 대한 ItemsControl
이없는 ScrollViewer
가상화의 핵심입니다. ItemsControl
( 컨트롤 템플릿을 템플릿으로 사용)에 대한 기본 컨트롤 템플릿에 추가 ListBox
하면 다음과 같은 이점이 있습니다.
<ItemsControl ItemsSource="{Binding AccountViews.Tables[0]}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Initialized="TextBlock_Initialized"
Text="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsVirtualizing="True"
VirtualizationMode="Recycling" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ScrollViewer CanContentScroll="True"
Padding="{TemplateBinding Padding}"
Focusable="False">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
(BTW, 기본 컨트롤 템플릿을 보기 위한 훌륭한 도구는 Show Me The Template입니다. )
주의 사항 :
설정해야합니다 . 이유 ScrollViewer.CanContentScroll="True"
는 여기 를 참조 하십시오 .
또한 VirtualizingStackPanel.VirtualizationMode="Recycling"
. 이렇게하면 TextBlock_Initialized
호출되는 횟수 가 줄어들지 만 화면에 많은 TextBlock이 표시됩니다. 여기
에서 UI 가상화에 대해 자세히 알아볼 수 있습니다 .
편집 : 명백한 상태로 잊어 버렸 : 대체 솔루션으로, 당신은 단지 대체 할 수 ItemsControl
와 함께 ListBox
🙂 또한이 체크 아웃 MSDN 페이지에 최적화 성능을 통보 ItemsControl
하는 이유입니다에없는 “성능을 구현하는 것이 제어가 특징”테이블, 컨트롤 템플릿을 편집해야합니다.
답변
DavidN의 답변을 바탕으로 ItemsControl에서 가상화 할 수있는 스타일은 다음과 같습니다.
<!--Virtualised ItemsControl-->
<Style x:Key="ItemsControlVirtualizedStyle" TargetType="ItemsControl">
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<Border
BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True"
>
<ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
ListBox를 사용하라는 제안이 마음에 들지 않습니다. 원치 않는 행을 선택할 수 있기 때문입니다.
답변
기본값 ItemsPanel
은 VirtualizingStackPanel
. 변경해야합니다.
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>