您的位置:首页 > 其它

ListView vs ListBox performance in WPF

2010-02-26 11:32 465 查看
I've been listing a relatively large number of items in a ListView (8000+) and it is great in terms of performance, fills in less than a second.

I've tried the same with a ListBox and it takes a lot more time. Even if I set the ItemsPanelTemplate to a VirtualStackPanel.

I'm using a (not default) DataTemplate for the items.

I'm very happy to continue to use a ListView instead of a ListBox, I'm just curious about the difference in performance.

Does anyone know why there's such a big difference? What am I missing?

===
ListBox already uses a VirtualizingStackPanel by default.

What do the items look like?

Are you using the same DataTemplate in the ListView?

Could you show us the DataTemplate?

==

The DataTemplate is this:

Code:
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="0" Background="White">
<Border Margin="5" BorderThickness="1" BorderBrush="SteelBlue" CornerRadius="4" Background="{Binding Path=Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}">
<Grid Margin="3">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="70"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Path=OutrosNomes}"></TextBlock>
<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="0">
<TextBlock Margin="0,5,0,5" FontWeight="Bold" Text="BI: "></TextBlock>
<TextBlock Margin="0,5,0,5" Text="{Binding Path=N_BI,Converter={StaticResource NumeroDefinidoConverter}}"></TextBlock>
<TextBlock Margin="0,5,0,5" FontWeight="Bold" Text=" NIF: "></TextBlock>
<TextBlock Margin="0,5,0,5" Text="{Binding Path=NIF,Converter={StaticResource NumeroDefinidoConverter}}"></TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Column="1" Grid.RowSpan="2" VerticalAlignment="Center">
<StackPanel.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}}" Value="False">
<Setter Property="StackPanel.Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<Button Grid.Column="0" Tag="{Binding .}" Width="20" Margin="5,0,0,0" ToolTip="Seleccionar" Click="SeleccionarButton_Click">
<Image Width="15" Height="15" Source="/UI/Imagens/CheckIcon.png" />
</Button>
</StackPanel>
</Grid>
</Border>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>


I'm also using the following "style" that changes the default ControlTemplate for the ListBox:

Code:
<Style TargetType="{x:Type ListBox}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Trebuchet MS" />
<Setter Property="FontSize" Value="12" />
<Setter Property="BorderBrush" Value="{DynamicResource ControlBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="1" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Grid>
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1" Background="{DynamicResource ControlBackgroundBrush}">
<ScrollViewer Margin="1" Focusable="false" Foreground="{TemplateBinding Foreground}">

<StackPanel Margin="2" IsItemsHost="true" />

</ScrollViewer>
</Border>
<Border x:Name="DisabledVisualElement" I****TestVisible="false" Background="#A5FFFFFF" BorderBrush="#66FFFFFF" BorderThickness="1" Opacity="0" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="DisabledVisualElement" Value="1" />
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>


Is there something in that Style that makes the VirtualizingStackPanel not work as expected?

===

Yeah, the censoring stuff on this forum is a bit naive.

First thing I notice is that in your Style for re-templating the ListBox, you have a normal StackPanel inside the ScrollViewer rather than a VirtualizingStackPanel. They're different classes. Switching that out might help you.

So instead of this...

Code:
XAML
<StackPanel Margin="2" IsItemsHost="true" />


You need this...

Code:
XAML
<VirtualizingStackPanel Margin="2" IsItemsHost="true" />


Let's see if that works.

==

Sorry for the late reply, I was on vacations :P

That was it, thanks!

I didn't expect that it was a problem with the template because, even when I set the ListBox.ItemsPanel's ItemsPanelTemplate as a VirtualizingStackPanel it didn't improve performance.
Probably that happens because the default template uses that property (ItemsPanel) and the overrinding ControlTemplate does not...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: