我有一个数据网格:
<DataGrid x:Name="Foo" ... />
我想将元素的高度绑定到数据网格的高度。简单地做{Binding ElementName=Foo, Path=ActualHeight}
是行不通的,因为它需要ScrollViewer
' 高度,而不是数据网格内容的总高度。
您需要找到 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 中找到ScrollViewer
andViewportHeight
<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
您的所有项目都相同的情况下才有效。
您可以将其包装DataGrid
在另一个中ScrollViewer
,然后 DataGrid 的实际高度将是正确的。
但是,这会带来性能损失,即无法利用DataGrid
. 您必须进行测试,看看这是否会对您的用例产生重大负面影响。