StackPanel.ActualHeight始终为零

3

我在运行时创建了一个 StackPanel,我想要测量 StackPanelHeight,代码如下:

StackPanel panel = new StackPanel();
panel.Children.Add(new Button() { Width = 75, Height = 25 });
Title = panel.ActualHeight.ToString();

但是ActualHeight总是为零。我该如何测量StackPanelHeight


ActualHeight 在渲染时将始终为25,因为StackPanel会无限增长以容纳其子元素。你想在这里实现什么? - Rohit Vats
正如我所说,我想创建一个 StackPanel 并在其上放置一些控件,然后通过 PrintDialog 打印它。 - mohammad
我已经发布了一个答案。看看它是否适合你。 - Rohit Vats
面板是否在屏幕上呈现?你能看到它吗? - alansiqueira27
4个回答

3
如果您想在UI中不加载内容时测量大小,则必须在包含的面板上调用MeasureArrange以复制GUI场景。
请注意WPF布局系统如何工作,面板首先调用Measure()方法,在该方法中,面板告诉其子项有多少可用空间,每个子项告诉其父项它需要多少空间。然后调用Arrange()方法,每个控件根据可用空间排列其内容或子项。
我建议在此处阅读更多相关信息:WPF布局系统
话虽如此,以下是手动执行的步骤:
StackPanel panel = new StackPanel();
panel.Children.Add(new Button() { Width = 75, Height = 25 });
panel.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
panel.Arrange(new Rect(0, 0, panel.DesiredSize.Width, panel.DesiredSize.Height));
Title = panel.ActualHeight.ToString();

1
天啊!我之前试过使用 double.NaN 而不是 double.PositiveInfinity,结果抛出了异常。从未考虑过尝试使用 PositiveInfinity - mcwyrm

0

我不完全确定你想做什么,但这段代码有效:

this.SetBinding(Window.TitleProperty, 
                new Binding()
                     {
                         Source = panel,
                         Path = new PropertyPath("ActualHeight")
                     });

通常情况下,直到堆栈面板被布局和渲染之后,您才能访问其大小。这发生在面板的Loaded事件之前,因此您可以处理该事件并在那时处理它。

我想创建一个StackPanel,并在上面放置一些控件,然后通过PrintDialog打印出来。 - mohammad

0
尝试在“Loaded”事件中获取“ActualHeight”:
private void Button_Click(object sender, RoutedEventArgs e)
{
    var panel = new StackPanel();
    var button = new Button();

    button.Width = 75;
    button.Height = 25;

    panel.Children.Add(button);
    panel.Loaded += new RoutedEventHandler(panel_Loaded);

    MainGrid.Children.Add(panel);
}

private void panel_Loaded(object sender, RoutedEventArgs e)
{
    Panel panel = sender as Panel;
    Title = panel.ActualHeight.ToString();
}

有没有一种方法可以在不将其添加到网格中的情况下引发已加载事件? - mohammad
你可以使用FrameworkTemplate.LoadContent来强制模板中的元素加载到临时可视树中,但这并不总是有用的。 - mcwyrm

0

试试这个:

panel.UpdateLayout(); //this line may not be necessary.
Rect bounds = VisualTreeHelper.GetDescendantBounds(panel);
var panelHeight = bounds.Height;

不,答案是负无穷大。 - mohammad
尝试调用UpdateLayout,就像我编辑问题时所做的那样(第一行)。 - alansiqueira27
你可以尝试将 StackPanel 放在 Grid 中,因为 StackPanel 在计算大小方面存在一些问题。 - alansiqueira27

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接