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

cit*_*nas 89 c# wpf tabcontrol docking

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

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

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

Ray*_*rns 179

WPF等效的WinForms的DockStyle.Fill是:

HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Run Code Online (Sandbox Code Playgroud)

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

常见错误

我现在将解释一些阻止HorizontalAlignment="Stretch" VerticalAlignment="Stretch"按预期工作的常见错误.

1.明确的高度或宽度

一个常见错误是明确指定控件的宽度或高度.所以,如果你有这个:

<Grid>
  <Button Content="Why am I not filling the window?" Width="200" Height="20" />
  ...
</Grid>
Run Code Online (Sandbox Code Playgroud)

只需删除Width和Height属性:

<Grid>
  <Button Content="Ahhh... problem solved" />
  ...
</Grid>
Run Code Online (Sandbox Code Playgroud)

2.包含面板挤压控制到最小尺寸

另一个常见的错误是让控制面板挤压你的控制装置.例如,垂直StackPanel将始终垂直地挤压其内容,尽可能小:

<StackPanel>
  <Button Content="Why am I squished flat?" />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

换到另一个Panel,你会很高兴:

<DockPanel>
  <Button Content="I am no longer squished." />
</DockPanel>
Run Code Online (Sandbox Code Playgroud)

此外,任何高度为"自动"的网格行或列同样会在该方向上挤压其内容.

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

  • 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>
Run Code Online (Sandbox Code Playgroud)

通常,您永远不希望任何Panel具有明确的高度或宽度.诊断布局问题的第一步是删除我能找到的每个显式高度或宽度.

4.窗口是SizeToContent,它不应该是

当您使用SizeToContent时,您的内容将被挤压到最小尺寸.在许多应用中,这是非常有用的,是正确的选择.但是如果你的内容没有"自然"大小,那么你可能想要省略SizeToContent.

  • 很好的答案!我希望我能以某种方式给你积分.:) (7认同)

Ber*_*ryl 7

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

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

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

    <MyFillingTabControl />
</DockPanel>
Run Code Online (Sandbox Code Playgroud)


and*_*dyp 5

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

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

  <Ribbon Grid.Row="0" />

  <TabPage Grid.Row="1" />
</Grid>
Run Code Online (Sandbox Code Playgroud)

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