ListBox 默認是UI虛擬化的。
1. 原生使用
- <ListBox VirtualizingPanel.IsVirtualizing="True"
- VirtualizingPanel.VirtualizationMode="Recycling">
- </ListBox>
為ListBox 設置一個ItemTemplate
- <DataTemplate x:Key="ListBoxDataTemplate">
- <Grid Loaded="Grid_Loaded">
- <Label Content="{Binding Name}"></Label>
- </Grid>
- </DataTemplate>
在 Grid_Loaded 事件中可以看到 實例化的次數
- int index = 0;
- private void Grid_Loaded(object sender, RoutedEventArgs e)
- {
- Console.WriteLine(index);
- index++;
- }
2. 當修改 ListBox 的Template屬性時 ,UI虛擬化就失效了
- <Setter Property="Template">
- <Setter.Value>
- <ControlTemplate TargetType="{x:Type ListBox}">
- <ScrollViewer x:Name="ScrollViewer" CanContentScroll="false">
- <ItemsPresenter />
- </ScrollViewer>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
這是標配寫法
ScrollViewer
中包裹
<
ItemsPresenter
/>
這時
ScrollViewer
控件的
CanContentScroll
=
"false"(物理滾動) 要改為
CanContentScroll
=
"true"(邏輯滾動)
ListBox 默認是邏輯滾動,(一項一項滾動)。改變模板時,需要重新設置
附件屬性 ScrollViewer.CanContentScroll="True" 這個時候Ui虛擬化重新出現
3.修改Listbox 的ItemsPanel 模板添加一下代碼也是可以ui虛擬化(除非你修改了ItemsPanel 模板,因為默認就是虛擬化的。)
- <Setter Property="ItemsPanel">
- <Setter.Value>
- <ItemsPanelTemplate >
- <VirtualizingStackPanel Orientation="Vertical"/>
- </ItemsPanelTemplate>
- </Setter.Value>
- </Setter>
全部代碼
- <Window x:Class="VirtualizingStackPanelDemo.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="MainWindow" Height="350" Width="525">
- <Window.Resources>
- <DataTemplate x:Key="ListBoxDataTemplate">
- <Grid Loaded="Grid_Loaded">
- <Label Content="{Binding Name}"></Label>
- </Grid>
- </DataTemplate>
- <Style x:Key="ListBoxStyle" TargetType="{x:Type ListBox}">
- <Setter Property="BorderThickness" Value="0"></Setter>
- <Setter Property="Margin" Value="0 0 5 0"></Setter>
- <Setter Property="MinWidth" Value="150"></Setter>
- <Setter Property="MaxHeight" Value="350"></Setter>
- <Setter Property="Height" Value="350"></Setter>
- <Setter Property="SnapsToDevicePixels" Value="True" />
- <Setter Property="ScrollViewer.CanContentScroll" Value="True"></Setter>
- <Setter Property="Template">
- <Setter.Value>
- <ControlTemplate TargetType="{x:Type ListBox}">
- <ScrollViewer x:Name="ScrollViewer" CanContentScroll="True">
- <ItemsPresenter />
- </ScrollViewer>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- <!--<Setter Property="ItemsPanel">
- <Setter.Value>
- <ItemsPanelTemplate >
- <VirtualizingStackPanel Orientation="Vertical"/>
- </ItemsPanelTemplate>
- </Setter.Value>
- </Setter>-->
- </Style>
- </Window.Resources>
- <Grid>
- <ListBox Style="{StaticResource ListBoxStyle}" ItemTemplate="{StaticResource ListBoxDataTemplate}" x:Name="listbox"></ListBox>
- </Grid>
- </Window>
總結 :
1.Listbox 默認虛擬化
2.修改ListBox Template時 ,重新設置ListBox 附加屬性ScrollViewer.CanContentScroll 為"True",以及
<
ScrollViewer
CanContentScroll
=
"True"
>
<
ItemsPresenter
/>
</
ScrollViewer
>