简体   繁体   English

ScrollViewer 正在禁用虚拟化,从而导致 WPF 性能下降

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

When I populate a ListView with 10000 rows of data, it is takes around 1 minute to launch the dialog.当我用 10000 行数据填充ListView时,启动对话框大约需要 1 分钟。 If I understand correctly, it is happening because ScrollViewer is turning off the virtualization of ListView (child).如果我理解正确的话,这是因为ScrollViewer正在关闭ListView (子)的虚拟化。 If I remove ScrollViewer , the dialog gets launched within 5 second.如果我删除ScrollViewer ,对话框会在 5 秒内启动。

My problem is I don't want to remove ScrollViewer and virtualization should work for ListView .我的问题是我不想删除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>

From the code mentioned below based on the type of tab, Usercontrol mentioned above containing Scrolllviewer and Listview is getting launched.根据下面提到的基于选项卡类型的代码,上面提到的包含 Scrolllviewer 和 Listview 的 Usercontrol 正在启动。 I have used Scrollviewer to scroll in case of usercontrol Zoom.在用户控制缩放的情况下,我使用 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>

Already tried things:已经尝试过的东西:

 <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> 

Setting up Maxheight of Listview inside constructor worked for me.在构造函数中设置 Listview 的 Maxheight 对我有用。 Previously i was setting up the Maxheight inside SizechangedEvent,thats why while loading it was not working and causing performance issue.以前我在 SizechangedEvent 中设置 Maxheight,这就是为什么在加载时它不起作用并导致性能问题。 And i have also used VirtualizingPanel.IsVirtualizingWhenGrouping="True" VirtualizingPanel.VirtualizationMode="Recycling" with Listview.而且我还在 Listview 中使用了 VirtualizingPanel.IsVirtualizingWhenGrouping="True" VirtualizingPanel.VirtualizationMode="Recycling"。 So moral of the story is you can Manually enable virtualization in ListView present inside Scrollviewer.所以故事的寓意是您可以在 Scrollviewer 中的 ListView 中手动启用虚拟化。

You do not have to do any of that.您不必执行任何这些操作。 ListView supports scrolling and virtualization by default. 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;
    }
}

This will load almost instantly.这将几乎立即加载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM