[英]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.