今天遇到个问题,加载多条数据时,界面卡顿,原始代码,大致如下:
<ScrollViewer VerticalScrollBarVisibility="Auto" >
<ItemsControl x:Name="itemsControl1" >
</ItemsControl>
</ScrollViewer>
后来尝试加上虚拟化相关设置发现,没起作用
<ScrollViewer VirtualizingPanel.IsVirtualizing="True" CanContentScroll="True" VirtualizingPanel.VirtualizationMode="Standard" >
<ItemsControl x:Name="itemsControl1" VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standard">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
最后的修改方案是把scrollviewer 写到ItemsControl.Template中去,才生效。
<ItemsControl x:Name="itemsControl2" Grid.Column="1" VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standard">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" CanContentScroll="True" >
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
补充
<ScrollViewer VirtualizingPanel.IsVirtualizing="True" CanContentScroll="True" VirtualizingPanel.VirtualizationMode="Standard" >
<ItemsControl Margin="20" x:Name="itemsControl1" Grid.Column="1" VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standard">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" CanContentScroll="True" >
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</ScrollViewer>
如果外面在嵌套一层scrollviewer 发现加载也会变得很慢。究其原因,是因为内层的scrollviewer没有设置最高上限,导致所有的数据项都加载出来了。 可以通过VerticalScrollBarVisibility="Visible" 设置(设置成Auto发现,里面的滚动条永远不会显示出来),将其显示出来,发现里面的滚动条是把所有的数据都加载出来了。
修改方法就是设置里面一层scrollviewer的maxheight,然后就不会出现界面卡顿的现象了。
附上完整的代码
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<ScrollViewer VirtualizingPanel.IsVirtualizing="True" CanContentScroll="True" VirtualizingPanel.VirtualizationMode="Standard" >
<ItemsControl Margin="20" x:Name="itemsControl1" Grid.Column="1" VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standard">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<!-- MaxHeight="200" -->
<ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" CanContentScroll="True" >
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</ScrollViewer>
<Border Grid.Column="1">
<ItemsControl x:Name="itemsControl2" Grid.Column="1" VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standard">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" CanContentScroll="True" >
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</Border>
<Button x:Name="button1" Grid.Row="1" Click="button1_Click"/>
<Button x:Name="button2" Grid.Row="1" Grid.Column="1" Click="button2_Click"/>
</Grid>
public partial class Window1 : Window
{
List<int> intList = new List<int>();
public Window1()
{
InitializeComponent();
for (int i = 0; i < 100000; i++)
intList.Add(i);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
itemsControl1.ItemsSource = intList;
}
private void button2_Click(object sender, RoutedEventArgs e)
{
itemsControl2.ItemsSource = intList;
}
}