Получение виртуализации пользовательского интерфейса, работающего с ItemsControl в Silverlight
Я пытаюсь создать прокручивающийся список довольно больших текстовых блоков. Я хочу, чтобы была вертикальная полоса прокрутки, чтобы показать их все, и если они превышают определенный размер, я хочу, чтобы они отображали многоточие. У меня на самом деле все это работает довольно хорошо.
У меня есть следующий Silverlight XAML:
<Grid x:Name="LayoutRoot" MaxWidth="500" MinWidth="100"
MaxHeight="500" MinHeight="100">
<Grid.DataContext>
<app:MainPageViewModel/>
</Grid.DataContext>
<ScrollViewer>
<ItemsControl ItemsSource="{Binding TextItems}" Margin="0,20,0,20">
<ItemsControl.ItemTemplate><DataTemplate>
<Border MaxHeight="175" Margin="0,0,0,18" CornerRadius="5">
<TextBlock Margin="2" TextTrimming="WordEllipsis"
TextWrapping="Wrap" Text="{Binding}"/>
</Border>
</DataTemplate></ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
Моя проблема заключается в том, что этот макет не использует виртуализацию пользовательского интерфейса, например, с VirtualizingStackPanel. Так что это довольно медленно. Каков наилучший способ включить виртуализацию пользовательского интерфейса в этот макет? Я пробовал около полудюжины разных способов, и ничего не получилось.
Мне удалось заставить это работать в ListBox, потому что он, кажется, поддерживает виртуализацию из коробки. Тем не менее, я бы предпочел использовать ItemsControl, так как я не хочу, чтобы эти вещи выбирались, и я не хочу, чтобы стиль, который поставляется вместе с ListBox.
Это в Silverlight 4.
1 ответ
Есть несколько вещей, которые вам нужно сделать, чтобы сделать эту работу.
- Установите для ItemsPanelTemplate для ItemsControl значение VirtualizingStackPanel.
- Включите ScrollViewer в ControlTemplate для ItemsControl вместо того, чтобы просто оборачивать его снаружи.
- Убедитесь, что ItemsControl имеет фиксированную высоту, чтобы система макетов могла определить, сколько элементов необходимо заполнить область просмотра. (Похоже, вы уже делаете это, помещая ItemsControl в Grid - это позволит системе макетов определить выделенную высоту для элемента управления)
Вот самый простой пример, который я мог бы придумать для этой работы:
<ItemsControl ItemsSource="{Binding TextItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border>
<ScrollViewer>
<ItemsPresenter/>
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>