WPF listbox UI虛擬化



ListBox  默認是UI虛擬化的。

1. 原生使用 
  
  
  
          
  1. <ListBox VirtualizingPanel.IsVirtualizing="True"
  2. VirtualizingPanel.VirtualizationMode="Recycling">
  3. </ListBox>

 為ListBox 設置一個ItemTemplate
   
   
   
           
  1. <DataTemplate x:Key="ListBoxDataTemplate">
  2. <Grid Loaded="Grid_Loaded">
  3. <Label Content="{Binding Name}"></Label>
  4. </Grid>
  5. </DataTemplate>
在 Grid_Loaded 事件中可以看到 實例化的次數
   
   
   
           
  1. int index = 0;
  2. private void Grid_Loaded(object sender, RoutedEventArgs e)
  3. {
  4. Console.WriteLine(index);
  5. index++;
  6. }
2. 當修改 ListBox   的Template屬性時 ,UI虛擬化就失效了

    
    
    
            
  1. <Setter Property="Template">
  2. <Setter.Value>
  3. <ControlTemplate TargetType="{x:Type ListBox}">
  4. <ScrollViewer x:Name="ScrollViewer" CanContentScroll="false">
  5. <ItemsPresenter />
  6. </ScrollViewer>
  7. </ControlTemplate>
  8. </Setter.Value>
  9. </Setter>
這是標配寫法 ScrollViewer 中包裹 < ItemsPresenter />

這時 ScrollViewer 控件的 CanContentScroll = "false"(物理滾動) 要改為 CanContentScroll = "true"(邏輯滾動)

ListBox 默認是邏輯滾動,(一項一項滾動)。改變模板時,需要重新設置
附件屬性 ScrollViewer.CanContentScroll="True" 這個時候Ui虛擬化重新出現

3.修改Listbox 的ItemsPanel 模板添加一下代碼也是可以ui虛擬化(除非你修改了ItemsPanel 模板,因為默認就是虛擬化的。)
   
   
   
           
  1. <Setter Property="ItemsPanel">
  2. <Setter.Value>
  3. <ItemsPanelTemplate >
  4. <VirtualizingStackPanel Orientation="Vertical"/>
  5. </ItemsPanelTemplate>
  6. </Setter.Value>
  7. </Setter>

全部代碼
    
    
    
            
  1. <Window x:Class="VirtualizingStackPanelDemo.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. Title="MainWindow" Height="350" Width="525">
  5. <Window.Resources>
  6. <DataTemplate x:Key="ListBoxDataTemplate">
  7. <Grid Loaded="Grid_Loaded">
  8. <Label Content="{Binding Name}"></Label>
  9. </Grid>
  10. </DataTemplate>
  11. <Style x:Key="ListBoxStyle" TargetType="{x:Type ListBox}">
  12. <Setter Property="BorderThickness" Value="0"></Setter>
  13. <Setter Property="Margin" Value="0 0 5 0"></Setter>
  14. <Setter Property="MinWidth" Value="150"></Setter>
  15. <Setter Property="MaxHeight" Value="350"></Setter>
  16. <Setter Property="Height" Value="350"></Setter>
  17. <Setter Property="SnapsToDevicePixels" Value="True" />
  18. <Setter Property="ScrollViewer.CanContentScroll" Value="True"></Setter>
  19. <Setter Property="Template">
  20. <Setter.Value>
  21. <ControlTemplate TargetType="{x:Type ListBox}">
  22. <ScrollViewer x:Name="ScrollViewer" CanContentScroll="True">
  23. <ItemsPresenter />
  24. </ScrollViewer>
  25. </ControlTemplate>
  26. </Setter.Value>
  27. </Setter>
  28. <!--<Setter Property="ItemsPanel">
  29. <Setter.Value>
  30. <ItemsPanelTemplate >
  31. <VirtualizingStackPanel Orientation="Vertical"/>
  32. </ItemsPanelTemplate>
  33. </Setter.Value>
  34. </Setter>-->
  35. </Style>
  36. </Window.Resources>
  37. <Grid>
  38. <ListBox Style="{StaticResource ListBoxStyle}" ItemTemplate="{StaticResource ListBoxDataTemplate}" x:Name="listbox"></ListBox>
  39. </Grid>
  40. </Window>

總結 :

1.Listbox 默認虛擬化

2.修改ListBox Template時 ,重新設置ListBox 附加屬性ScrollViewer.CanContentScroll 為"True",以及
< ScrollViewer CanContentScroll = "True" >
< ItemsPresenter />
</ ScrollViewer >







免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM