如何在窗口显示之前计算实际宽度和高度?

3

我试图在窗口显示之前(例如在窗口构造函数中)计算位于网格的中间单元格中的StackPanel宽度高度。如何实现?

<Window x:Class="WpfApplication2.TestWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="TestWindow" Height="300" Width="300">
<Grid Name="grid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>

    <StackPanel Grid.Row="1" Grid.Column="1" Name="stackPanel"></StackPanel>

</Grid>

对于窗口和堆栈面板,DesiredSize被设置为{0;0}

。需要进行测量。

public partial class TestWindow : Window
{
    public TestWindow()
    {
        InitializeComponent();

        this.Measure(new Size(this.Width, this.Height)); // -> this.DesiredSize = {0;0}

        ...

    }
}

编辑1

以下适用于FixedPage:

fixedPage.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 
fixedPage.Arrange(new Rect(0, 0, fixedPage.DesiredSize.Width, fixedPage.DesiredSize.Height));

那么我们可以访问stackPanel.ActualWidthstackPanel.ActualHeight

但对于窗口,它不起作用。

1个回答

2

尝试使用Loaded事件:

public TestWindow()
{
    InitializeComponent();
    this.Loaded += new RoutedEventHandler(TestWindow_Loaded);
}

void TestWindow_Loaded(object sender, RoutedEventArgs e)
{
    //this.DesiredSize shouldnt be {0,0} now
}

编辑:由于StackPanel即使没有任何项也会占用最大的Size,因此其SizeChanged事件只有在添加太多项时才会触发,因此您可以像这样使用StackPanelSizeChanged事件:

private void spTest_SizeChanged(object sender, SizeChangedEventArgs e)
{
    if (!(e.PreviousSize.Height == 0 && e.PreviousSize.Width == 0)) //will also be fired after loading
    {
        //Create another Page
    }
}

编辑2: 另一种可能的解决方案:

public MainWindow()
{
    InitializeComponent();
    yourStackPanelName.Loaded += new RoutedEventHandler(yourStackPanelName_Loaded);
}

void yourStackPanelName_Loaded(object sender, RoutedEventArgs e)
{
    double height = ((StackPanel)sender).ActualHeight;
    double width = ((StackPanel)sender).ActualWidth;
}

它适用于 Windows,但这里的 Window 只是举例。我需要将网格放置到 FixedPage 中,并且必须找到 stackPanel 的尺寸作为此页面的内容区域 - 这有助于回答我可以在其中放置多少项... 对于每个项目,我定义 Mesure,现在是高度,然后当我到达页面末尾时,我需要创建另一页,以此类推... - user1897059
为什么需要设置StackPanel的高度和宽度?如果StackPanel没有子项,它会自动占据父元素的高度和宽度,因此您不需要通过代码来设置这些属性。 - Florian Gl
1
我想要获取高度和宽度,而不是设置它们。正如之前所问,我需要这个来找出在 stackPanel 中可能的项目计数。如果我把更多的项目放进去,它们将在 FixedPage 上看不见。 - user1897059
谢谢,但这对我不适用。每次您使用Loaded事件将DocumentViewer滚动到FixedPage时,它都会被执行... - user1897059
也许你应该发布更多的程序代码,这样我们才能知道什么适合你。 - Florian Gl
对于FixedPage解决方案,需要执行以下步骤:1. 运行fixedPage.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 2. 执行fixedPage.Arrange(new Rect(0, 0, fixedPage.DesiredSize.Width, fixedPage.DesiredSize.Height)); 3. 访问stackPanel.ActualWidth和stackpanel.ActualHeight。但是对于WINDOW,这种方法不起作用。 - user1897059

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