XAML元素填充所有剩余空间

Fre*_*oot 3 c# wpf xaml

我有一个WPF应用程序,我正在尝试正确定位元素.只有四个元素,所以它应该是非常简单的,但我不能让它工作.

一个问题是,当窗口出现时,窗口会将其自身调整为(大约)桌面窗口的大小,因此它没有固定的大小.

这些元素应该从上到下堆叠,因此Stack Panel看起来很自然.但是第三个元素必须占据前两个和底部没有的剩余空间.无论我尝试什么,它要么占用太多空间,要么占用太少空间.如果我给它一个具体的像素大小,我似乎只能让它工作,如上所述,它将无法工作.

我尝试过的最新产品是Dock Panel.虽然它在Visual Studio设计器中看起来是正确的,但在执行时,第三个元素 - Canvas - 完全覆盖了底部元素.

我的XAML:

<DockPanel>
    <Button x:Name="btnClose" DockPanel.Dock="Top" Content="X" 
            HorizontalAlignment="Right" Margin="0,5,5,0" VerticalAlignment="Top" 
            Width="Auto" Height="Auto" Background="Black" 
            Foreground="White" Click="btnClose_Click"/>
    <Label x:Name="lblTitle" DockPanel.Dock="Top" Content="My Title" 
           HorizontalAlignment="Center" VerticalAlignment="Top" Width="Auto" 
           Foreground="White" FontWeight="Bold" FontSize="22"/>

    <Label x:Name="lblControls" DockPanel.Dock="Bottom" Content="Placeholder" 
           HorizontalAlignment="Center" VerticalAlignment="Bottom" Width="Auto" 
           Height="Auto" Foreground="White" FontWeight="Bold" FontSize="22"/>

    <Border x:Name="CanvasBorder" BorderBrush="White" BorderThickness="5" >
        <Canvas x:Name="cvsChart" Grid.Row="0" HorizontalAlignment="Stretch"
                VerticalAlignment="Top" Width="Auto">
        </Canvas>
    </Border>
</DockPanel>
Run Code Online (Sandbox Code Playgroud)

有关如何让Canvas伸展并填充其他三个不占用的空间的任何想法?

更新 由于@Peter Duniho几乎向我证明代码有效,我尝试了一个实验并删除了我在窗口出现时的调整代码.拿出来,窗口看起来绝对正确.这就是我要将其大小调整为(大部分)桌面大小的方法:

public const int WINDOW_OFFSET = 10;
...

int screenWidth = (int)System.Windows.SystemParameters.PrimaryScreenWidth;
int screenHeight = (int)System.Windows.SystemParameters.PrimaryScreenHeight;

// center this window in desktop
Width = screenWidth - WINDOW_OFFSET;
Height = screenHeight - WINDOW_OFFSET;
Left = WINDOW_OFFSET/2;
Top = WINDOW_OFFSET/2;
Run Code Online (Sandbox Code Playgroud)

所以我做了一些讨论,并在'Stack上发现了一条评论说要获得WorkArea而不是PrimaryScreenHeight.我试过了,瞧!,出现整个应用程序窗口.

int screenWidth = (int)System.Windows.SystemParameters.WorkArea.Width;
int screenHeight = (int)System.Windows.SystemParameters.WorkArea.Height;
Run Code Online (Sandbox Code Playgroud)

事实证明,底行显示,我无法看到它,因为它出现下面的屏幕的底部.现在我可以看到它,我又回到了发展天堂!

感谢大家的投入!

Pet*_*iho 6

有许多可能的方法.最简单的一种方法是在a中包含你的元素Grid,并将除第三行高度以外的所有元素设置为Auto:

  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto"/>
      <RowDefinition Height="Auto"/>
      <RowDefinition/>
      <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Button x:Name="btnClose" Content="X" Grid.Row="0"
            HorizontalAlignment="Right" Margin="0,5,5,0" VerticalAlignment="Top" 
            Width="Auto" Height="Auto" Background="Black" 
            Foreground="White" Click="btnClose_Click"/>
    <Label x:Name="lblTitle" Content="My Title" Grid.Row="1"
           HorizontalAlignment="Center" VerticalAlignment="Top" Width="Auto" 
           Foreground="White" FontWeight="Bold" FontSize="22"/>

    <Label x:Name="lblControls" Content="Placeholder" Grid.Row="3"
           HorizontalAlignment="Center" VerticalAlignment="Bottom" Width="Auto" 
           Height="Auto" Foreground="White" FontWeight="Bold" FontSize="22"/>

    <Border x:Name="CanvasBorder" BorderBrush="White" BorderThickness="5" Grid.Row="2">
      <Canvas x:Name="cvsChart" Grid.Row="0" HorizontalAlignment="Stretch"
                VerticalAlignment="Top" Width="Auto">
      </Canvas>
    </Border>
  </Grid>
Run Code Online (Sandbox Code Playgroud)

网格行定义高度的默认设置是"*",表示使用该设置分配所有行中的所有剩余空间.只有一行使用该设置,它将获得所有剩余空间.

这会产生一个如下所示的窗口:

四行网格,边框和画布填充第三行

(我将窗口背景设置为Gray可以显示白色文本和边框.)

实际上另一种选择是使用DockPanel.在我看来,你尝试的主要问题是你将lblControls元素设置为DockPanel.Dock="Bottom"应该的时间Top.当我改变它时Top,它似乎对我来说很好.

根据你在下面的评论,你似乎确实想要lblControls设置DockPanel.Dock="Bottom",事实上你发布的代码似乎也做你想要的.我不清楚你发布的代码与你想要它做什么有什么不同.如果您提供一个可靠地再现问题的良好的Minimal,Complete和Verifiable代码示例会更好.