94

我从 windows 窗体中使用,我创建一个面板,在其中放置控件并将它们DockStyle.Fill的大小最大化到周围的面板。

在 WPF 中,我希望拥有相同的功能。我有一个 TabControl,我希望它的大小尽可能多地填充表单。我有一个功能区控件(RibbonControlsLibrary),并希望表单的其余部分以最大尺寸填充 TabControl。

(我不想像停靠在 Visual Studio 中那样停靠控件,只是旧的停靠机制)

4

4 回答 4

185

WinForms 的 DockStyle.Fill 的 WPF 等效项是:

HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

这是几乎控件的默认设置,因此通常您无需执行任何操作即可让 WPF 控件填充其父容器:它们会自动执行此操作。对于所有不将其子级压缩到最小尺寸的容器都是如此。

常见错误

我现在将解释几个阻止HorizontalAlignment="Stretch" VerticalAlignment="Stretch"按预期工作的常见错误。

1. 显式高度或宽度

一个常见的错误是显式指定控件的宽度或高度。所以如果你有这个:

<Grid>
  <Button Content="Why am I not filling the window?" Width="200" Height="20" />
  ...
</Grid>

只需删除 Width 和 Height 属性:

<Grid>
  <Button Content="Ahhh... problem solved" />
  ...
</Grid>

2. 包含面板将控件压缩到最小尺寸

另一个常见的错误是让包含面板尽可能紧地挤压您的控制。例如,一个垂直的 StackPanel 将始终垂直压缩其内容,使其尽可能小:

<StackPanel>
  <Button Content="Why am I squished flat?" />
</StackPanel>

更改为另一个面板,您会很高兴:

<DockPanel>
  <Button Content="I am no longer squished." />
</DockPanel>

此外,高度为“自动”的任何 Grid 行或列都将类似地向该方向挤压其内容。

不挤压其子容器的一些示例是:

  • ContentControls 从不挤压他们的孩子(这包括 Border、Button、CheckBox、ScrollViewer 等)
  • 具有单行和单列的网格
  • 带有“*”大小的行和列的网格
  • DockPanel 不会挤压它的最后一个孩子
  • TabControl 不会压缩其内容

确实会挤压孩子的容器的一些示例是:

  • StackPanel 在其 Orientation 方向上挤压
  • 具有“自动”大小的行或列的网格沿该方向挤压
  • DockPanel 在其停靠方向上挤压除最后一个孩子以外的所有孩子
  • TabControl 挤压其标题(选项卡上显示的内容)

3. 显式高度或宽度

令人惊讶的是,我看到 Grid 或 DockPanel 有多少次给出明确的高度和宽度,如下所示:

<Grid Width="200" Height="100">
  <Button Content="I am unnecessarily constrainted by my containing panel" />
</Grid>

一般来说,你永远不想给任何面板一个明确的高度或宽度。诊断布局问题的第一步是删除我能找到的每个显式高度或宽度。

4. 窗口不应该是 SizeToContent

当您使用 SizeToContent 时,您的内容将被压缩到最小尺寸。在许多应用中,这非常有用并且是正确的选择。但是,如果您的内容没有“自然”大小,那么您可能希望省略 SizeToContent。

于 2010-07-11T17:47:12.783 回答
7

你可以做你想做的事,只要说DockPanel LastChildFill="True",然后确保你想成为的填充物实际上是最后一个孩子!

Grid 是布局中的野兽,您几乎可以做任何事情,但 DockPanel 通常是您最外层布局面板的正确选择。这是一个伪代码示例:

<DockPanel LastChildFill="True">
    <MyMenuBar DockPanel.Dock="Top"/>
    <MyStatus DockPanel.Dock="Bottom"/>

    <MyFillingTabControl />
</DockPanel>
于 2010-07-09T20:04:01.150 回答
5

只需将控件包装在两行的网格中。网格将自动使用给它的所有空间,您可以通过给它们高度“*”来定义行以占用所有剩余空间。我的示例中的第一行 (Height="Auto") 将占用功能区所需的空间。希望有帮助。

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>

  <Ribbon Grid.Row="0" />

  <TabPage Grid.Row="1" />
</Grid>

通过将“Grid.Row=..”属性添加到网格的子控件,它们被分配给网格的行。然后网格将根据行定义来确定其子项的大小。

于 2010-07-09T19:51:11.253 回答
0

我在这里尝试了很多方法,但无法解决我的问题。(在控件中填写其他控件)

直到我找到

<Name_Control Height="auto" Width="auto"/>
//default
//HorizontalAlignment="Stretch" 
//VerticalAlignment="Stretch"

例子:

//UserControl:
<UserControl Name="UC_Test" Height="auto" Width="auto" />
//Grid: 
<Grid Name="Grid_test" Grid.ColumnSpan="2" Grid.Row="2" />
//Code: 
Grid_test.Children.Add(UC_Test);

为了便于设计

<UserControl Name="UC_Test" Height="100" Width="100" />
//Code
Grid_test.Children.Add(UC_Test);
UC_Test.Width = Double.NaN;
UC_Test.Height = Double.NaN;
于 2016-11-24T19:24:01.300 回答