【问题标题】:How to enable UI virtualization in Standard WPF ListView如何在标准 WPF ListView 中启用 UI 虚拟化
【发布时间】:2013-01-22 10:12:33
【问题描述】:

我使用的是 .NET 4.5/VS2012,我的 ListView 看起来像这样

<ListView 
    VirtualizingPanel.IsContainerVirtualizable="True"
    VirtualizingPanel.IsVirtualizing="True"
    VirtualizingPanel.IsVirtualizingWhenGrouping="True"
    Grid.Row="1"
    Name="eventLogList"
    Margin="5,0,5,0"
    BorderBrush="Black"
    BorderThickness="2"
    ItemsSource="{Binding EventLogs}"
    SelectedItem="{Binding SelectedEventLog}"
    local:ListViewSorter.CustomListViewSorter="EventLogViewer.UI.EventLogItemComparer"
    SelectionMode="Single">

    <ListView.GroupStyle>
        <GroupStyle HidesIfEmpty="False">
            <GroupStyle.ContainerStyle>
                <Style TargetType="GroupItem">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="GroupItem">
                                <Expander IsExpanded="True">
                                    <Expander.Header>
                                        <TextBlock FontSize="20" TextWrapping="Wrap" Margin="0,10,0,5" >
                                        <Bold><TextBlock Text="{Binding Name}"/></Bold> - <TextBlock FontSize="20" Text="{Binding ItemCount}"/> logs
                                    </TextBlock>
                                    </Expander.Header>
                                    <ItemsPresenter/>
                                </Expander>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </GroupStyle.ContainerStyle>
        </GroupStyle>
    </ListView.GroupStyle>
    <ListView.View>
        <GridView>
            <GridViewColumn 
                Header="event id"
                Width="120"
                DisplayMemberBinding="{Binding EventID}" />
            <GridViewColumn 
                Header="level"
                Width="160"
                DisplayMemberBinding="{Binding Level}" />
            <GridViewColumn 
                Header="server" 
                Width="160"
                DisplayMemberBinding="{Binding Server}" />
            <GridViewColumn 
                Header="log name" 
                Width="160"
                DisplayMemberBinding="{Binding LogName}" />
            <GridViewColumn 
                Header="source"
                Width="240"
                DisplayMemberBinding="{Binding Source}" />
            <GridViewColumn 
                Header="logged"
                Width="240"
                DisplayMemberBinding="{Binding Logged}" />
        </GridView>
    </ListView.View>
</ListView>

但性能仍然没有提高。我找到了一个使用 ListBox 的示例,但是如何虚拟化 ListView?我很挣扎。 我听说在分组的情况下,以前版本的 WPF 中关闭了虚拟化,但是在 .NET 4.5 中,WPF 有一个IsVirtualizingWhenGrouping 属性,我已经将它设置为True

更新:罪魁祸首是自定义样式,删除后,列表视图运行流畅如黄油

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    “UI 虚拟化仅将可见项存储在内存中但在数据绑定场景中将整个数据结构存储在内存中。相比之下,数据虚拟化仅存储在屏幕上可见的数据项在内存中。”

    “默认情况下,当 ListView 和 ListBox 控件的列表项绑定到数据时,会启用 UI 虚拟化。”

    For more info view the original MSDN source.

    【讨论】:

      【解决方案2】:

      This的文章对你有很大帮助。也可以看看..

      【讨论】:

      • 第二个链接没有多大帮助,因为我预算紧张,买不起商业链接,至于 MSDN 的讨论,我还在消化,我确实使用了一些自定义样式,会尝试禁用它们进行测试。
      • 禁用自定义样式后,问题解决。不过,正在寻找一种两全其美的方法。
      【解决方案3】:

      我知道这是一个老问题,但我发现它是为了寻找我的问题的答案,并想分享我的发现,以防它对其他人有用。我遇到了一个非常相似的情况,即没有虚拟化的 ListView 控件。我删除了我在它上面的自定义样式(在阅读了这个线程和相关链接之后),它开始正确地进行虚拟化。

      经过大量调查,与默认模板进行比较并缩小范围后,我发现它是该模板内 ScrollContentPresenter 上的“CanContentScroll”属性。我根本没有设置它,当我将它设置为 true 时,它​​开始正确虚拟化。我还注意到默认模板有 'CanHorizo​​ntallyScroll="False"' 和 'CanVerticallyScroll="False"';我在有限的测试中可以看出这些似乎没有什么不同(我相信有人可以插话并说出他们的所作所为),但我还是把它们留在了那里。

      这是我的最终样式(请注意,这是从默认开始并修改的,所以不确定 CanContentScroll 属性在哪里被删除...):

      <Style x:Key="{x:Static GridView.GridViewScrollViewerStyleKey}"
         TargetType="ScrollViewer">
          <Setter Property="Template">
              <Setter.Value>
                  <ControlTemplate TargetType="ScrollViewer">
                      <Grid Background="{TemplateBinding Background}">
                          <Grid.ColumnDefinitions>
                              <ColumnDefinition Width="*"/>
                              <ColumnDefinition Width="Auto"/>
                          </Grid.ColumnDefinitions>
                          <Grid.RowDefinitions>
                              <RowDefinition Height="*"/>
                              <RowDefinition Height="Auto"/>
                          </Grid.RowDefinitions>
      
                          <DockPanel Margin="{TemplateBinding Padding}">
                              <ScrollViewer DockPanel.Dock="Top"
                                            HorizontalScrollBarVisibility="Hidden"
                                            VerticalScrollBarVisibility="Hidden"
                                            Focusable="false">
                                  <GridViewHeaderRowPresenter Margin="2,0,2,0"
                                                              Columns="{Binding Path=TemplatedParent.View.Columns, RelativeSource={RelativeSource TemplatedParent}}"
                  ColumnHeaderContainerStyle="{Binding
                               Path=TemplatedParent.View.ColumnHeaderContainerStyle,
                               RelativeSource={RelativeSource TemplatedParent}}"
                  ColumnHeaderTemplate="{Binding
                               Path=TemplatedParent.View.ColumnHeaderTemplate,
                               RelativeSource={RelativeSource TemplatedParent}}"
                  ColumnHeaderTemplateSelector="{Binding 
                               Path=TemplatedParent.View.ColumnHeaderTemplateSelector,
                               RelativeSource={RelativeSource TemplatedParent}}"
                  AllowsColumnReorder="{Binding
                               Path=TemplatedParent.View.AllowsColumnReorder,
                               RelativeSource={RelativeSource TemplatedParent}}"
                  ColumnHeaderContextMenu="{Binding
                               Path=TemplatedParent.View.ColumnHeaderContextMenu,
                               RelativeSource={RelativeSource TemplatedParent}}"
                  ColumnHeaderToolTip="{Binding
                               Path=TemplatedParent.View.ColumnHeaderToolTip,
                               RelativeSource={RelativeSource TemplatedParent}}"
                  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                              </ScrollViewer>
      
                              <ScrollContentPresenter Name="PART_ScrollContentPresenter"
                                                      KeyboardNavigation.DirectionalNavigation="Local" 
                                                      CanContentScroll="True"
                                                      CanHorizontallyScroll="False"
                                                      CanVerticallyScroll="False"/>
                          </DockPanel>
      
                          <ScrollBar Name="PART_HorizontalScrollBar"
                                     Orientation="Horizontal"
                                     Grid.Row="1"
                                     Maximum="{TemplateBinding ScrollableWidth}"
                                     ViewportSize="{TemplateBinding ViewportWidth}"
                                     Value="{TemplateBinding HorizontalOffset}" 
                                     Style="{StaticResource StScrollBarNoMargin}"
                                     Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
      
                          <ScrollBar Name="PART_VerticalScrollBar"
                                     Grid.Column="1"
                                     Style="{StaticResource StScrollBarNoMargin}"
                                     Maximum="{TemplateBinding ScrollableHeight}"
                                     ViewportSize="{TemplateBinding ViewportHeight}"
                                     Value="{TemplateBinding VerticalOffset}"
                                     Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
      
                      </Grid>
                  </ControlTemplate>
              </Setter.Value>
          </Setter>
      </Style>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-12
        • 1970-01-01
        相关资源
        最近更新 更多