我有一个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>
有关如何让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;
所以我做了一些讨论,并在'Stack上发现了一条评论,说要获取WorkArea而不是PrimaryScreenHeight。我试过了,瞧!,整个应用程序窗口出现了。
int screenWidth = (int)System.Windows.SystemParameters.WorkArea.Width;
int screenHeight = (int)System.Windows.SystemParameters.WorkArea.Height;
事实证明,底行 显示,我只是看不到它,因为它出现在屏幕下方的下面。现在我可以看到它,我又回到了发展的天堂!
感谢大家的投入!
答案 0 :(得分:5)
有很多可能的方法。最简单的方法之一是将您的元素包含在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>
网格行定义高度的默认设置为"*"
,表示使用该设置分配所有行中的所有剩余空间。只有一行使用该设置,它将获得所有剩余空间。
这会产生一个如下所示的窗口:
(我将窗口背景设置为Gray
,以便您的白色文字和边框可见。)
另一种选择实际上是使用 DockPanel
。在我看来,您尝试的主要问题是将lblControls
元素设置为DockPanel.Dock="Bottom"
,而应该是Top
。当我将其更改为Top
时,它似乎对我来说很好。
根据您在下面的评论,您似乎确实希望将lblControls
设置为DockPanel.Dock="Bottom"
,实际上您发布的代码似乎也可以执行您想要的操作。我不清楚与您发布的代码有什么不同以及您希望它做什么。如果你提供一个可靠地再现问题的好Minimal, Complete, and Verifiable code example会更好。
答案 1 :(得分:2)
删除画布的垂直对齐