wpf scrollviewer的虚拟化失效问题

今天遇到个问题,加载多条数据时,界面卡顿,原始代码,大致如下:

  <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;
        }
    }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值