#wpf #silverlight #virtualizingstackpanel
#wpf #silverlight #virtualizingstackpanel
Вопрос:
У меня есть ItemsControl с VirtualizingStackPanel в качестве панели элементов, подобной этой:
<ItemsControl Style="{StaticResource ItemsControl}" Name="itemsControl"
Margin="0,100,0,0" HorizontalAlignment="Stretch" Height="80">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Стиль следующий:
<Style x:Key="ItemsControl" TargetType="ItemsControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer VerticalScrollBarVisibility="Hidden"
HorizontalScrollBarVisibility="Visible">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Я установил коллекцию из 100 000 элементов в качестве источника ItemsSource и получил действительно хорошую производительность. Все в порядке, за исключением одной вещи. Когда я ввожу текст в одно из текстовых полей, а затем начинаю прокручивать, я вижу, что этот текст появляется повсюду в списке!
Я понимаю, что делает VirtualizingStackPanel. Он непрерывно загружает элементы, которые становятся видимыми при прокрутке. Я понимаю некоторые аспекты его техники виртуализации, но я понятия не имею, как понять это странное поведение. Мне не удалось найти хорошие документы по виртуализации WPF / Silverlight, поэтому, пожалуйста, объясните мне, что происходит
Комментарии:
1. У меня была такая же проблема с переключателями в datagird, и я решил ее, добавив отдельный шаблон редактирования для каждой ячейки. Благодаря @Rachel, теперь понятно, как решать такого рода проблемы
Ответ №1:
VirtualizingStackPanel
фактически не загружает элементы непрерывно. Вместо этого он повторно использует существующие элементы (элементы управления) и просто заменяет DataContext за ними.
Поэтому, если у вас есть VirtualizingStackPanel
100 000 элементов, и одновременно видны только 10, обычно отображается около 14 элементов (дополнительные элементы для буфера прокрутки). При прокрутке изменяется DataContext за этими 14 элементами управления, но сами фактические элементы управления никогда не будут заменены.
Если вы делаете что-то вроде ввода текста в текстовое поле # 1, и TextBox.Text
это ни к чему не привязано, тогда текст всегда будет отображаться, потому что элемент управления используется повторно. Если вы привяжете значение TextBox.Text
к значению, то DataContext изменится при прокрутке, что заменит отображаемый текст.
Ответ №2:
Не уверен, как отключить переработку непосредственно в VirtualizingStackPanel, но это синтаксис в ListBox. Я бы опубликовал в качестве комментария, но мне нужен был форматированный код.
<ListBox VirtualizingStackPanel.VirtualizationMode="Standard" />
Комментарии:
1. Вы все равно можете добавлять строки кода в комментарии, используя ввод a
backtick around your code block
, хотя он не окрашивает его и не позволяет выполнять несколько строк2. Это клавиша, которая находится над клавишей [Tab] на стандартной клавиатуре США. Он разделяет ключ с тильдой (
~
).