如何在WPF中使用DockStyle.Fill作为标准控件?

问题描述 投票:0回答:5

我从 Windows 窗体中使用,我创建一个面板,将控件放置在其中并给它们

DockStyle.Fill
以最大程度地扩大其周围面板的大小。

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

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

c# wpf tabcontrol docking
5个回答
189
投票

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>

只需删除宽度和高度属性即可:

<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>

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

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

  • 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。


7
投票

您只需说

DockPanel
LastChildFill="True"
即可做您想做的事,然后确保您想要填充的实际上是最后一个孩子!

网格是布局中的野兽,您可以用它来做大多数事情,但 DockPanel 通常是最外层布局面板的正确选择。这是一个伪代码示例:

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

    <MyFillingTabControl />
</DockPanel>

5
投票

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

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

  <Ribbon Grid.Row="0" />

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

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


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;

0
投票

如果您因为想将 UserControl 放入某些东西而到达这里,但它无法拉伸。

在 XAML 中更改以下内容

Height="600" Width="800"

d:DesignHeight="600" d:DesignWidth="800"
© www.soinside.com 2019 - 2024. All rights reserved.