【发布时间】:2012-06-23 01:25:14
【问题描述】:
我有这种风格的数据网格:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter"
Grid.Column="1"
Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
CanContentScroll="{TemplateBinding CanContentScroll}"
Grid.ColumnSpan="2"
Grid.Row="1" />
<ScrollBar x:Name="PART_VerticalScrollBar"
Grid.Column="2"
Maximum="{TemplateBinding ScrollableHeight}"
Orientation="Vertical"
Grid.Row="1"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
ViewportSize="{TemplateBinding ViewportHeight}"/>
<Grid Grid.Column="1" Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollBar x:Name="PART_HorizontalScrollBar"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableWidth}"
Orientation="Horizontal"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
</Grid>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<Grid>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Grid.Row="0" />
<Canvas Width="128"
VerticalAlignment="Stretch"
HorizontalAlignment="Left"
Grid.Row="0"
x:Name="Image" />
</Grid>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
我知道,如果您在数据网格上加载大量数据,性能会受到影响。我可以使用虚拟化来减轻对性能的影响,但是,一旦我将网格放入自定义滚动查看器中,虚拟化就会丢失。
我正在尝试取回它,但我不确定如何——同时在我的 XAML 中仍然保留名为 Image 的元素。
基本上,我想让图像与数据网格内容一起滚动,上面的代码可以正常工作,只是我不知道如何启用虚拟化。有没有可能?
更新:看来我发现了一个问题。模板中的最后一个Grid 导致问题:
<Grid>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Grid.Row="0" />
<Canvas Width="128"
VerticalAlignment="Stretch"
HorizontalAlignment="Left"
Grid.Row="0"
x:Name="Image" />
</Grid>
只要我把Canvas 和Grid 拿出来,只留下ItemsPresenter,然后它又很快了。我怎样才能快速获得它并且仍然保留这个Canvas?
更新 2:如何将这个 (ScrollViewer slow perfomance with DataGrid) 策略应用于上面显示的 Grid?我试过这个:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Rectangle Name="sizingElement" Grid.Row="0" Fill="Transparent" Margin="1"/>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Grid.Row="0"
Height="{Binding ElementName=sizingElement, Path=ActualHeight, FallbackValue=1}" />
<Canvas Width="128"
VerticalAlignment="Stretch"
HorizontalAlignment="Left"
Grid.Row="0"
x:Name="Image" />
</Grid>
但是,现在滚动条消失了?
我意识到我无法虚拟化 Canvas,我也不需要。事实上,整个Canvas 都被绘制出来了,我没有逻辑将它分成更小的部分。完全渲染图像是完全可以的,只要我可以保持行虚拟化。
【问题讨论】:
-
我不知道 Grid 支持虚拟化。 ¿ 你是如何实现它的?
-
我的意思是 DataGrid 支持虚拟化。
-
我记得 DataGrid 中的 ScrollViewer 破坏了 DataGrid 虚拟化,但我找不到它。是只读的吗。如果是这样,试试 GridView - 它会快得多。
-
@Blam 如果我删除多余的
Canvas元素,我对DataGrid没有任何问题。因此,DataGrid本身没有问题,实际上即使在这种情况下ListView也很慢。 -
@Blam 显然,滚动查看器会导致虚拟化问题,因为它要求孩子占据全高,以便查看器可以测量其大小并相应地显示滚动条,但只要孩子(数据网格) 高度化,虚拟化消失了。
标签: c# .net wpf performance