3

我有一个数据网格:

<DataGrid x:Name="Foo" ... />

我想将元素的高度绑定到数据网格的高度。简单地做{Binding ElementName=Foo, Path=ActualHeight}是行不通的,因为它需要ScrollViewer' 高度,而不是数据网格内容的总高度。

4

2 回答 2

2

您需要找到 DataGrid 的 internal ScrollViewer,并绑定到它的ViewportHeight

根据您对该值的用途以及您需要它的位置,可以通过多种方式完成此操作。

通常这种事情对于仅查看目的是必需的,所以我会将代码放在 CodeBehind 中查找 ViewPort 高度

例如,使用一些VisualTreeHelpers,您可以执行以下操作:

// Find first child of type ScrollViewer in object Foo
var scrollViewer = VisualTreeHelpers.FindChild<ScrollViewer>(Foo);

// If object is found, set other control's height to ViewportHeight
if (scrollViewer != null)
{
    MyControl.Height = scrollViewer.ViewportHeight;
}

我不记得是否有超过一个ScrollViewer......DataGrid你必须使用像Snoop这样的东西才能确定。如果有,则按.FindChild()名称查找您应该能够使用的元素的重载。这个名字也可以通过像 Snoop 这样的东西来获得。

这也可以在 a 中完成Converter,您将在其中传递DataGrid给 Converter,并让它在 Converter 中找到ScrollViewerandViewportHeight

<Grid Height="{Binding ElementName=Foo, 
                       Converter={StaticResource GetDataGridContentHeight}}" />

编辑

我实际上做了一些测试,DataGridScrollViewer处理大小的方式有点不同,可能是由于Virtualization. 它似乎使用基于行数的相对大小。

DataGrid我正在使用的测试有 23 行。ScrollViewer.ExtentHeight等于 23,并且是 3,这ScrollViewer.ViewportHeight意味着总共有 23 行,并且显示了 3 个完整的行。等于 20,这ScrollViewer.ScrollableHeight意味着我可以从 0 滚动到 20(因为显示了 3 个项目,所以不需要转到 23),并且ScrollViewer.VerticalOffset被设置为我当前滚动到的任何项目。

因此,要获得 virtualized 中项目的实际内容高度ScrollViewer,我认为您将必须获得ActualHeight其中一个可见行的 ,并将其乘以ScrollViewer.ExtentHeight以获得内容的实际大小。这仅在Height您的所有项目都相同的情况下才有效。

于 2012-06-22T14:12:33.047 回答
0

您可以将其包装DataGrid在另一个中ScrollViewer,然后 DataGrid 的实际高度将是正确的。

但是,这会带来性能损失,即无法利用DataGrid. 您必须进行测试,看看这是否会对您的用例产生重大负面影响。

于 2012-06-22T13:16:32.610 回答