【发布时间】:2014-04-08 19:27:46
【问题描述】:
我有一个 ListBox,用于显示通过 ObservableCollection<T> 绑定到 ItemsSource 的多种类型的项目(都派生自同一个基类型)。
说的 ListBox 的性能很糟糕。似乎禁用了虚拟化。根据:http://msdn.microsoft.com/en-us/library/cc716879(v=vs.110).aspx 看来,向 ItemsControl 添加多种类型的项目可能是问题所在。
这是我的 ListBox 的样式:
<Style x:Key="{x:Type ListBox}" TargetType="{x:Type ListBox}">
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="VirtualizingPanel.VirtualizationMode" Value="Recycling" />
<Setter Property="VirtualizingPanel.IsVirtualizing" Value="True" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Visible" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Grid Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentPresenter Content="{StaticResource ListHeader}" />
<ScrollViewer Grid.Row="1" Margin="0" Focusable="False">
<VirtualizingStackPanel Margin="2" IsItemsHost="True" />
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
绑定ObservableCollection<T> 中的每种可能类型都有DataTemplates,它们都是派生自同一个基类的类。一个示例 DataTemplate 是:
<DataTemplate DataType="{x:Type ma:TimerEvent}">
<Grid Background="{StaticResource TargetCalledBackgroundColor}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="ShotNumberColumn" />
<ColumnDefinition Width="Auto" SharedSizeGroup="ShotTimeColumn" />
<ColumnDefinition Width="Auto" SharedSizeGroup="SplitTimeColumn" />
<ColumnDefinition Width="Auto" SharedSizeGroup="TargetNumberColumn" />
<ColumnDefinition Width="Auto" SharedSizeGroup="TotalTimeColumn" />
<ColumnDefinition Width="Auto" SharedSizeGroup="ScoreColumn" />
</Grid.ColumnDefinitions>
<Image Source="/LASR;component/Assets/Announcement.png" Width="16" Height="16" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock Grid.Column="1" Grid.ColumnSpan="2" Foreground="{StaticResource TargetCalledForegroundColor}" Text="{Binding DisplayText}" TextAlignment="Center" />
<TextBlock Grid.Column="3" Foreground="{StaticResource TargetCalledForegroundColor}" Text="{Binding TargetNumberCalled}" TextAlignment="Center" />
<TextBlock Grid.Column="4" Foreground="{StaticResource TargetCalledForegroundColor}" Text="{Binding Path=TotalTime.TotalSeconds, StringFormat={}{0:0.00}}" TextAlignment="Center" />
</Grid>
</DataTemplate>
ListBox XAML 在这里:
<UserControl>
<Grid>
<ListBox ItemsSource="{Binding}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
</UserControl>
WPF 窗口的层次结构是:
<Window>
<Grid>
<Grid Name="MainWindowContent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="340*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<GroupBox Grid.Row="1" Grid.Column="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<UserControl />
</Grid>
</GroupBox>
</Grid>
</Grid>
</Window>
是否有解决此问题的方法,或者任何人都可以看到任何其他可能关闭虚拟化的原因?
您可以下载an example project here。
谢谢。
【问题讨论】:
-
添加不同类型的数据项不会影响虚拟化。 MSDN 说:Item containers 直接添加到 ItemsControl。。例如,那将是
ListBoxItem和ComboBoxItem。 -
确保您没有将 ListBox 放入“无限容器”,例如 StackPanel 或 ScrollViewer。发布 ListBox 所在的 UI 的完整 XAML。
-
另外,你的数据项是什么类型的?
-
所有数据项都派生自同一个基类。 ListBox 位于以 Grid 作为其容器的 UserControl 内部。
-
用户控件包含在几个网格和一个 GroupBox 中,但没有 StackPanels
标签: .net wpf xaml listbox virtualization