GridViewColumn的CellTemplate的性能问题

时间:2017-05-04 10:46:55

标签: wpf performance listview gridview

我正在使用ListView,它的View设置为GridView,以显示动态生成的列中的项目。 ListView的虚拟化已启用。对于此示例,我想显示最多10行,每列50列(但列数是动态的)。

我要做的第一件事就是在循环中创建代码中的列。 “Items”只是我的视图模型中一行的ObservableCollection字符串。

int index = 0;

foreach(Header header in Headers)
{
  GridViewColumn column = new GridViewColumn();
  column.Header = // the view model of the header;
  column.HeaderTemplate = Resources["HeaderTemplate"] as DataTemplate;
  column.DisplayMemberBinding = new Binding("Items" + "[" + index + "]");
  m_MyGridView.Columns.Add(column);

  index++;
}

现在,当我更改ListView的ItemsSource时,数据会快速安静地更新。

不幸的是,每个单元格中的每个字符串都必须格式化(字体颜色,前景等)。所以我不能使用DisplayMemberBinding,而是使用CellTemplate为每个单元格分配一个DataTemplate。

为此,我在我的控件中的xaml中创建了一个DataTemplate,它包含ListView。它只包含一个TextBlock,其中包含一些与单元视图模型属性的绑定,以定义TextBlock的字符串样式。 现在,Items不仅仅是一个字符串集合,而是一个CellViewModel集合,它不仅包含要显示的值,还包含如何显示它的信息。然后,此信息将绑定在DataTemplate中。

CellTemplate在代码中设置并分配给每个GridViewColumn的CellTemplate:

foreach(Header header in Headers)
{
  GridViewColumn column = new GridViewColumn();
  column.Header = // the view model of the header;
  column.HeaderTemplate = Resources["HeaderTemplate"] as DataTemplate;
  column.CellTemplate = createCellTemplate(index);
  m_MyGridView.Columns.Add(column);

  index++;
}

DataTemplate getCellTemplate(int index)
{
  FrameworkElementFactory elementFactory = new FrameworkElementFactory (typeof (ContentControl));

  elementFactory.SetBinding(ContentControl.ContentProperty, new Binding("Items" + "[" + index + "]"));

  DataTemplate dt = Resources["ValueTemplate"] as DataTemplate;
  elementFactory.SetValue(ContentControl.ContentTemplateProperty, dt);
  DataTemplate dataTemplate = new DataTemplate ();
  dataTemplate.VisualTree = elementFactory;

  return dataTemplate;
}

当我这样做时,当我更改ListView的ItemsSource时,事情变得非常缓慢。现在每次更改ItemsSource以显示不同数据时,现在需要将近一秒的时间来渲染新单元格。

那么有没有办法加快速度?我想通过使用Paragraph将格式化的字符串放在我的CellViewModel中,但不幸的是DisplayMemberBinding只支持字符串,所以我必须使用CellTemplate。

编辑:所以,这是我正在使用的列表视图:

<ListView ItemsSource="{Binding ElementName=Control, Path=ItemViewModels}">
  <ListView.ItemsPanel>
    <ItemsPanelTemplate>
      <VirtualizingStackPanel IsItemsHost="True" VirtualizingStackPanel.IsVirtualizing="True" />
    </ItemsPanelTemplate>
   </ListView.ItemsPanel>
   <ListView.View>
     <GridView x:Name="m_MyGridView"/>
   </ListView.View>
</ListView>

和单元格的DataTemplate:

<DataTemplate x:Key="ValueTemplate">
    <Border Background="{Binding Path=BackgroundColor">
        <TextBlock Text="{Binding Path=Value}"
             Foreground="{Binding Path=ForegroundColor}"
             FontStyle="{Binding Path=FontStyle}"
             FontWeight="{Binding Path=FontWeight}"
        </TextBlock>
    </Border>
</DataTemplate>

创建标题时,只调用一次getCellTemplate函数。当ItemsSource更改时,它不会被调用,因为它们已经创建。

0 个答案:

没有答案
相关问题