【问题标题】:Parent measures to children size父母衡量孩子的大小
【发布时间】:2026-02-08 01:45:02
【问题描述】:

我正在编写一个自定义面板,我想知道如何告诉我的孩子,当他们需要重新测量时,他们的父母也应该进行重新测量。

例如,其中一个孩子改变了它的宽度,父母也应该再次重新测量,导致他的父母也进行重新测量,然后他的父母的父母和他父母的父母等等......就像上升VisualTree。我该怎么做?

这是面板的测量代码.. 但是如何告诉父母也重新测量

protected override Size MeasureOverride(Size availableSize)
{
 double x;
 double y;
 var children = this.InternalChildren;
 for (int i = 0; i < children.Count; i++)
     {
       UIElement child = children[i];
       child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity);
       y += child.DesiredSize.Height;
       x = Math.Max(x, child.DesiredSize.Width);
      }
 return new Size(x, y);
}

【问题讨论】:

  • 你不要那样做。它是由 WPF 自动完成的。试试吧。
  • 它不会自动执行.. 如果我告诉面板您的尺寸为 200 x 200,然后我将孩子的宽度更改为 300,则面板不会更新.. 这是我的我在问这个问题
  • 您需要提供更多信息,说明您要实现的目标以及原因并显示一些代码。如果我们只能猜测,* 的人将无法提供帮助。
  • 这是我的帖子。有代码*.com/questions/14775226/…
  • 如果信息相同,那么您不应该发布另一个问题。如果它不同并且需要另一个问题,那么请花时间在此处提供信息。另外,您是否尝试过针对其他问题给出的建议?

标签: wpf wpf-controls


【解决方案1】:

看看这个在左上角排列子元素的非常简单的自定义面板:

public class MyPanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        Trace.TraceInformation("MeasureOverride");

        var size = new Size();

        foreach (UIElement element in InternalChildren)
        {
            element.Measure(availableSize);

            size.Width = Math.Max(size.Width, element.DesiredSize.Width);
            size.Height = Math.Max(size.Height, element.DesiredSize.Height);
        }

        return size;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        Trace.TraceInformation("ArrangeOverride");

        foreach (UIElement element in InternalChildren)
        {
            element.Arrange(new Rect(element.DesiredSize));
        }

        return finalSize;
    }
}

如果您将其与 Button 子项一起使用,如下所示

<local:MyPanel>
    <local:MyPanel>
        <Button Width="100" Height="100" Click="Button_Click"/>
    </local:MyPanel>
</local:MyPanel>

以及调整按钮大小的 Button_Click 处理程序

private void Button_Click(object sender, RoutedEventArgs e)
{
    ((FrameworkElement)sender).Width += 20;
}

您会观察到,在每次单击按钮时,父面板和祖父面板都会被测量和排列。跟踪输出如下所示:

CustomPanelTest.vshost.exe Information: 0 : MeasureOverride
CustomPanelTest.vshost.exe Information: 0 : MeasureOverride
CustomPanelTest.vshost.exe Information: 0 : ArrangeOverride
CustomPanelTest.vshost.exe Information: 0 : ArrangeOverride

因此无需在父面板上手动调用MeasureArrange

【讨论】:

  • 我将 200x200 传递给我的面板,然后将该值传递给孩子们.. 但是当我调整孩子的大小时,面板没有得到更新和重新测量,所以我猜它不适合我,因为我正在使用固定大小值。我需要做什么才能让它工作
  • 当您希望面板对子元素的大小变化做出动态反应时,您永远不应该固定面板的大小。
  • 好吧,我在面板中的 measureoverride 中返回 200x200 作为尺寸,但是一旦任何子项的宽度大于 200,面板就不会再次测量
  • 您或许应该发布您的 MeasureOverride 和 ArrangeOverride 代码。
  • 200x200 的东西在哪里?你的ArrangeOverride 也会很有趣。