8

我从处理 WPF 中的子类化 Panel 并实现自己的布局工作以及获取 Infinity 或 PositiveInfinity 的人那里发现了一些其他问题,该维度传递给 availableSize arg 中的 MeasureOverride。回答通常是,“这意味着您可以占用尽可能多的空间:忽略它,将所有孩子的所需尺寸相加并返回。”

就我而言,我正在制作一个动态调整大小以填充可用空间的控件,因此没有所需大小的内在概念。它只想使用整个可用大小。

当我构建 ControlTemplate 时,它​​最终嵌套在 StackPanel 中,并且它开始为可用高度获取 Infinity,即使控件没有滚动条。如果我只是将它限制在某个固定数字,它只会夹在窗口上。我尝试返回 ActualHeight,但这不起作用,因为它是周期性的:在我完成完整的布局传递之前没有 ActualHeight。所以那总是0.0。

刚开始不知道是StackPanel下Infinity,翻了一阵子参考源也没有用,最后用VisualTreeHelper跑遍了父母,看他们的ActualHeight,发现StackPanel是最深的高度非零。我把它改成了 DockPanel,因为我只需要两个控件,所以它和 StackPanel 一样有效。看哪,DockPanel 没有通过 Infinity 的可用高度。

但这只是一种解决方法。我想更深入地了解布局背后的理念以及为什么没有滚动条的标准容器之一会告诉我我可以拥有尽可能多的空间。对此的“正确”回应是什么?

4

2 回答 2

2

这个:

我正在制作一个动态调整大小以填充可用空间的控件,

是一个不好的组合:

它最终嵌套在 StackPanel 中

“填充空间”的控件不应位于堆栈面板内。你认为它应该是多大的尺寸?

当然 ScrollPanel 也是如此。

于 2012-05-17T18:32:09.850 回答
1

好吧,我也离线与其他人交谈过,这是我的最佳理解:

如果您想使用 LayoutTransform 或 RenderTransform 进行更复杂的布局,从而在控件的测量/排列通道和它出现的实际像素边界之间添加间接性,告诉所有堆叠控件它们可以占用尽可能多的空间的行为正如他们想要的那样是合理的,因为您只是试图布局到与屏幕上实际剪切区域分离的表面。

感觉这仍然属于“如果你将 StackPanel 包装在可滚动的东西中......”的类别,但不可否认,在我建议的版本中,一旦你开始弄乱 StackPanel 的 RenderTransform,availableSize 应该是什么。(尽管它比这更基本;RenderTransform 并没有在设计上与 MeasureOverride “玩得很好”,因为它的设计与性能的布局机制分开......所以仍然不清楚这是一个很好的论点。)

在任何情况下,一种获取 StackPanel 行为的方法,其中某些选定项目消耗其他元素未使用的剩余部分是使用 DockPanel,将 StackPanels 中的固定大小元素推到顶部或底部,动态调整大小的元素要么在顶部或底部或两个堆栈之间的中间。

我想如果我需要多个元素按比例消耗可用空间,这就是 Grid 的用途。

但是我不得不说,我仍然不明白为什么 StackPanel 在调用 MeasureOverride 时将 Infinity 向下传递给它的子元素;我看不出你为什么不传递 StackPanel 的父级传入的实际剩余无人认领的可用大小的论据,以及你为什么要传递的几个论据。

于 2012-05-18T20:38:06.993 回答