WPF ListBox虚拟化和ItemsControl中的多个类型

时间:2014-04-08 19:27:46

标签: .net wpf xaml listbox virtualization

我有一个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

感谢。

1 个答案:

答案 0 :(得分:1)

通过ColumnDefinitions删除SharedSizeGroups

},您的示例项目中的效果彻底得到改善
<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>

SharedSizeGroup所需的计算过重,如果您有大量商品,则应避免使用。

改为使用ListView