C# 在MeasureOverride(WPF面板)中,当我没有内在的所需大小时,如何处理availableSize中的无穷大值?

C# 在MeasureOverride(WPF面板)中,当我没有内在的所需大小时,如何处理availableSize中的无穷大值?,c#,wpf,mvvm,C#,Wpf,Mvvm,我还发现了一些其他问题,这些问题来自于处理WPF中Panel子类化和实现自己的布局工作的人员,以及在availableSize参数中获得传递给MeasureOverride的维度的无穷大或正整数。回答通常是:“这意味着你可以占据你想要的任何空间:忽略它,把你所有孩子想要的尺寸加起来,然后返回。” 在我的例子中,我正在制作一个动态调整大小以填充可用空间的控件,因此没有所需大小的内在概念。它只是想使用整个可用的大小 当我构建ControlTemplate时,它最终嵌套在StackPanel中,并且对

我还发现了一些其他问题,这些问题来自于处理WPF中Panel子类化和实现自己的布局工作的人员,以及在availableSize参数中获得传递给MeasureOverride的维度的无穷大或正整数。回答通常是:“这意味着你可以占据你想要的任何空间:忽略它,把你所有孩子想要的尺寸加起来,然后返回。”

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

当我构建ControlTemplate时,它最终嵌套在StackPanel中,并且对于可用的高度,它开始变得无限大,即使控件没有滚动条。如果我只是把它固定在某个固定的数字上,它就会夹在窗户上。我试着返回实际高度,但这不起作用,因为它是周期性的:在我完成完整的布局传递之前,没有实际高度。所以一直都是0.0

起初,我不知道是StackPanel传递了无穷大,在参考源中挖掘了一段时间,但没有结果,最后,我通过使用VisualTreeHelper遍历父母并查看他们的实际高度,找到了答案,StackPanel是高度非零的最深的一个。我把它改成了DockPanel,因为我只需要两个控件,所以它和StackPanel一样工作。看哪,DockPanel并没有通过可用高度的无穷大

但这感觉就像是一个解决办法;我想更深入地理解布局背后的理念,以及为什么一个没有滚动条的标准容器会告诉我可以有我想要的空间。对此的“正确”回答是什么?

这是:

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

是与以下内容的糟糕组合:

它最终嵌套在StackPanel中

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


当然,滚动面板也是如此

好吧,在与其他人进行了离线交谈之后,我的理解如下:

如果您希望使用LayoutTransform或RenderTransform进行更复杂的布局,从而在控件的测量/排列过程和它所显示的实际像素边界之间添加间接性,告诉所有堆叠控件它们可以占据任意多的空间的行为是合理的,因为您只是试图布局到一个与屏幕上实际剪裁区域分离的曲面

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

在任何情况下,一种获取堆栈面板的行为的方法是:使用一个DokPoad,将固定大小的元素推到顶部或底部的堆叠面板中,在顶部或底部或两个堆栈之间的中间可动态调整大小。 我想,如果我需要多个元素以比例的方式消耗可用空间,这就是网格的用途


但我必须说,我仍然无法从原则的角度理解为什么StackPanel在调用MeasureOverride时会将其方向无限传递给其子代;我看不到为什么不传递StackPanel的父级传入的实际剩余无人认领可用大小的任何参数,也没有看到为什么不传递的几个参数。

您无法对可用空间进行控件填充。在ScrollViewer中它应该做什么?显然,将这样的控件放在提供概念上无限空间的容器中是没有意义的。但是“您不能创建一个控件来填充可用空间”?这显然不是真的。考虑一下像WiDrStAT这样的应用程序…或者一个照片查看器,它可以在调整图像大小时向上缩放图像以填充窗口。我感到困惑的是,出于某种原因,StackPanel的行为就像它有无限的空间一样,尽管与ScrollViewer或SizeToContent窗口不同,没有明确的理由说明它应该这样做,也没有明确的理由说明它不应该这样做。但我明白你的意思。有一个明确的理由不应该这样做:这个参数被称为“可用空间”,对于非滚动容器,“可用空间”唯一有意义的概念是屏幕上的像素!除非你能想出一个例子,你希望你的控件剪辑到不可滚动的容器的边缘,并且有一个块不能被渲染。。。这似乎从来没有用过(而且你可以选择通过超出可用空间来实现。)是的,我想我的问题是,为什么?或者,我怎么知道?StackPanel是不可滚动的-为什么它不从它的第一个内容开始,将堆栈面板的完整可用大小减去边距、填充等传递给它,然后将该控件不使用的任何内容传递给下一个?我认为滚动面板很明显。但是DockPanel不这样做,它传递约束。从概念上讲,我不清楚为什么StackPanel在堆栈维度中有“无限”的可用空间,而DockPanel没有,而这两个维度都可以包含沿该轴的多个元素。StackPanel有点像Tardis:内部比外部大。是故意的。有没有。。。有什么原因吗?或者这只是生活中的一个谜团?凭设计通常就足够了。为什么要限制它的内部?通常你