簡體   English   中英

如何在標准WPF ListView中啟用UI虛擬化

[英]How to enable UI virtualization in Standard WPF ListView

我正在使用.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

更新 :罪魁禍首是自定義樣式,刪除后,列表視圖像黃油一樣平穩運行

“UI虛擬化僅在內存中存儲可見項目, 但在數據綁定方案中將整個數據結構存儲在內存中 。相比之下,數據虛擬化僅存儲內存中屏幕上可見的數據項。”

“默認情況下,當列表項綁定到數據時,會為ListView和ListBox控件啟用UI虛擬化。”

有關詳細信息,請查看原始MSDN源。

這篇文章對你有很大幫助。也可以看到..

我知道這是一個老問題,但我遇到它尋找我的問題的答案,並希望分享我發現的,以防它對其他人有用。 我有一個非虛擬化的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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM