簡體   English   中英

ScrollViewer 正在禁用虛擬化,從而導致 WPF 性能下降

[英]ScrollViewer is disabling virtualization thus causing slow performance in WPF

當我用 10000 行數據填充ListView時,啟動對話框大約需要 1 分鍾。 如果我理解正確的話,這是因為ScrollViewer正在關閉ListView (子)的虛擬化。 如果我刪除ScrollViewer ,對話框會在 5 秒內啟動。

我的問題是我不想刪除ScrollViewer並且虛擬化應該適用於ListView

<Grid>
    <!--if we remove this scrollviewer then performance will drastically improve-->
     <ScrollViewer  HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <ListView Name="variablelist" Grid.ColumnSpan="4"  ItemsSource="{Binding VariableList}" 
                  SelectedItem="{Binding SelectedRow}" IsEnabled="{Binding ListViewVariablesIsEnabled}" 
                  SelectionMode="Single" Foreground="Black" ScrollViewer.CanContentScroll="True" 
                  ScrollViewer.VerticalScrollBarVisibility="Visible"  Margin="0,26,0,10" Grid.RowSpan="2" 
                  KeyDown="variablelist_KeyDown">
            <ListView.View>
                <GridView>
                    <GridViewColumn  Width="{Binding VariableNameWidth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                        <GridViewColumnHeader Content="{x:Static p:Resources.listviewColumnName}" Command="{Binding SortCommand}" CommandParameter="Name" HorizontalContentAlignment="Left"/>
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Path=Name}" TextTrimming="CharacterEllipsis" ToolTip="{Binding Path=Name}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn  Width="{Binding VariableScopeWidth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                      <GridViewColumnHeader Content="{x:Static p:Resources.listviewColumnScope}" Command="{Binding SortCommand}" CommandParameter="Scope" HorizontalContentAlignment="Left"/>
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Path=Scope}" TextTrimming="CharacterEllipsis" ToolTip="{Binding Path=Scope}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>                           
                </GridView>
            </ListView.View>
        </ListView>
    </ScrollViewer>
</Grid>

根據下面提到的基於選項卡類型的代碼,上面提到的包含 Scrolllviewer 和 Listview 的 Usercontrol 正在啟動。 在用戶控制縮放的情況下,我使用 Scrollviewer 進行滾動。

<Grid >
            <Grid.RowDefinitions>
                <RowDefinition MaxHeight="20"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
                <Grid.LayoutTransform>
                    <ScaleTransform ScaleX="{Binding ElementName=ZoomSlider, Path=Value}" 
                                ScaleY="{Binding ElementName=ZoomSlider, Path=Value}" />
                </Grid.LayoutTransform>               
                <TextBlock Name="TitleBar" Text="{Binding Title}" ></TextBlock>
            </Border>
            <TabControl x:Name="pTAB" Grid.Row="1"
                    ItemsSource="{Binding TabItems}" 
                    SelectedItem="{Binding SelectedTab}">
                <TabControl.Resources>
                    <Style TargetType="{x:Type TabItem}">
                        <Setter Property="VerticalAlignment" Value="Bottom"/>                       
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type TabItem}">
                                    <Grid>
                                        <Border Name="Border"
                                            HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
                                            <TextBlock x:Name="TitleContent"
                                                   VerticalAlignment="Center" 
                                                   HorizontalAlignment="Center" 
                                                   Text="{TemplateBinding Header}">
                                            </TextBlock>
                                        </Border>
                                    </Grid>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </TabControl.Resources>
            </TabControl>
        </Grid>

        <Slider x:Name="ZoomSlider" Grid.Row="1" Orientation="Horizontal" 
                Minimum="1.0" Maximum="2.0" LargeChange="0.25" SmallChange="0.01"  Value="1.0" Visibility="Hidden" />
    </Grid>

已經嘗試過的東西:

 <ListView Name="variablelist" Grid.ColumnSpan="4"  ItemsSource="{Binding VariableList}" 
         SelectedItem="{Binding SelectedRow}" IsEnabled="{Binding ListViewVariablesIsEnabled}" 
         SelectionMode="Single" Foreground="Black" ScrollViewer.CanContentScroll="True" 
         ScrollViewer.VerticalScrollBarVisibility="Visible"  Margin="0,26,0,10" Grid.RowSpan="2" 
         KeyDown="variablelist_KeyDown" VirtualizingPanel.IsVirtualizing="True" 
  VirtualizingPanel.IsVirtualizingWhenGrouping="True"
  VirtualizingPanel.VirtualizationMode="Recycling">
 ......
</ListView> 

在構造函數中設置 Listview 的 Maxheight 對我有用。 以前我在 SizechangedEvent 中設置 Maxheight,這就是為什么在加載時它不起作用並導致性能問題。 而且我還在 Listview 中使用了 VirtualizingPanel.IsVirtualizingWhenGrouping="True" VirtualizingPanel.VirtualizationMode="Recycling"。 所以故事的寓意是您可以在 Scrollviewer 中的 ListView 中手動啟用虛擬化。

您不必執行任何這些操作。 ListView 默認支持滾動和虛擬化。

<ListView ItemsSource="{Binding BigList}">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding}"/>
        </GridView>
    </ListView.View>
</ListView>

public class MainWindowViewModel : INotifyPropertyChanged
{
    public IEnumerable<string> BigList { get; }

    public MainWindowViewModel()
    {
        var list = new List<string>();
        for (int i = 0; i < 10000; i++)
            list.Add(i.ToString());
        BigList = list;
    }
}

這將幾乎立即加載。

暫無
暫無

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

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