我有一个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)
事实证明,底行被显示,我无法看到它,因为它出现下面的屏幕的底部.现在我可以看到它,我又回到了发展天堂!
感谢大家的投入!
有许多可能的方法.最简单的一种方法是在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代码示例会更好.