web-dev-qa-db-ja.com

WPFの標準コントロールにDockStyle.Fillを使用する方法は?

私は、Windowsフォームから使用します。パネルを作成し、その中にコントロールを配置して、DockStyle.Fillサイズを周囲のパネルに最大化します。

WPFでも同じものが欲しいです。 TabControlがあり、そのサイズでフォームをできるだけいっぱいにしたい。リボンコントロール(RibbonControlsLibrary)があり、フォームの残りの部分に最大サイズのTabControlを入力する必要があります。

(Visual Studioでのドッキングのようなコントロールをドッキングしたくない、古いドッキングメカニズムだけ)

87
citronas

WinFormsのDockStyle.Fillに相当するWPFは次のとおりです。

HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

これはほとんどのコントロールのデフォルトであるため、-通常、親コンテナにWPFコントロールを設定するために何もする必要はありません:これらは自動的に行われます。これは、子を最小サイズに絞り込まないすべてのコンテナに当てはまります。

よくある間違い

ここで、HorizontalAlignment="Stretch" VerticalAlignment="Stretch"期待どおりに動作しません。

1。明示的な高さまたは幅

よくある間違いの1つは、コントロールの幅または高さを明示的に指定することです。これがある場合:

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

幅と高さの属性を削除するだけです:

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

2。パネルを含むと、コントロールが最小サイズに絞り込まれます

もう1つのよくある間違いは、含まれているパネルでコントロールをきつく締めることです。たとえば、垂直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は向きの方向に絞ります
  • その方向に「自動」サイズの行または列の絞りがあるグリッド
  • DockPanelは、最後の子を除くすべてをドック方向に絞ります
  • TabControlはヘッダーを圧縮します(タブに表示されるもの)

。明示的な高さまたは幅をさらに広げる

次のように、明示的な高さと幅が指定されたGridまたはDockPanelを何度も表示するのは驚くべきことです。

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

一般的に、どのパネルにも明示的な高さまたは幅を与えたくありません。レイアウトの問題を診断するときの最初のステップは、見つけられるすべての明示的なHeightまたはWidthを削除することです。

4。ウィンドウは、あるべきではないときにSizeToContentです

SizeToContentを使用すると、コンテンツは最小サイズに圧縮されます。多くのアプリケーションでこれは非常に便利であり、正しい選択です。ただし、コンテンツに「自然な」サイズがない場合は、おそらくSizeToContentを省略した方がよいでしょう。

175
Ray Burns

DockPanelLastChildFill="True"と言って、フィラーになりたいものが実際に最後の子であることを確認するだけで、望むことを実行できます。

グリッドは、ほとんど何でもできるレイアウトの獣ですが、DockPanelは通常、最も外側のレイアウトパネルに適した選択肢です。擬似コードの例を次に示します。

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

    <MyFillingTabControl />
</DockPanel>
7
Berryl

コントロールを2行のグリッドにラップするだけです。グリッドは、指定されたすべてのスペースを自動的に使用します。行に高さ「*」を指定すると、残りのスペースをすべて占有するように行を定義できます。この例の最初の行(Height = "Auto")は、リボンで必要なだけのスペースを取ります。お役に立てば幸いです。

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

  <Ribbon Grid.Row="0" />

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

「Grid.Row = ..」属性をグリッドの子コントロールに追加することにより、グリッドの行に割り当てられます。次に、グリッドは行定義で定義されたとおりに子のサイズを設定します。

5
andyp

ここで多くの方法を試してみましたが、問題を解決できません。 (コントロール内の他のコントロールを埋める)

見つかるまで it

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