StackPanelの子が最大スペースを下に埋めるにはどうすればよいですか?


356

単純に左側にフローテキスト、右側にヘルプボックスを表示します。

ヘルプボックスが一番下まで伸びているはずです。

StackPanel下のアウターを取り出すと上手くいきます。

しかし、レイアウトの理由から(ユーザーコントロールを動的に挿入しています)、ラッピングが必要StackPanelです。

試してみGroupBoxたように、をの下部まで拡張するにはどうすればよいですかStackPanel

  • VerticalAlignment="Stretch"
  • VerticalContentAlignment="Stretch"
  • Height="Auto"

XAML:

<Window x:Class="TestDynamic033.Test3"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Test3" Height="300" Width="600">
    <StackPanel 
        VerticalAlignment="Stretch" 
        Height="Auto">

        <DockPanel 
            HorizontalAlignment="Stretch" 
            VerticalAlignment="Stretch" 
            Height="Auto" 
            Margin="10">

            <GroupBox 
                DockPanel.Dock="Right" 
                Header="Help" 
                Width="100" 
                Background="Beige" 
                VerticalAlignment="Stretch" 
                VerticalContentAlignment="Stretch" 
                Height="Auto">
                <TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap" />
            </GroupBox>

            <StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch">
                <TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/>
            </StackPanel>

        </DockPanel>
    </StackPanel>
</Window>

回答:

おかげマークは、使用するDockPanel代わりに、StackPanelそれをクリアしました。一般に、私DockPanelはWPFレイアウトにますます使用していることに気づきました。修正されたXAMLは次のとおりです。

<Window x:Class="TestDynamic033.Test3"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Test3" Height="300" Width="600" MinWidth="500" MinHeight="200">
    <DockPanel 
        VerticalAlignment="Stretch" 
        Height="Auto">

        <DockPanel 
            HorizontalAlignment="Stretch" 
            VerticalAlignment="Stretch" 
            Height="Auto" 
            MinWidth="400"
            Margin="10">

            <GroupBox 
                DockPanel.Dock="Right" 
                Header="Help" 
                Width="100" 
                VerticalAlignment="Stretch" 
                VerticalContentAlignment="Stretch" 
                Height="Auto">
                <Border CornerRadius="3" Background="Beige">
                    <TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap" 

                Padding="5"/>
                </Border>
            </GroupBox>

            <StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch">
                <TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/>
            </StackPanel>

        </DockPanel>
    </DockPanel>
</Window>

書式設定を修正しました-リストからコードに直接進むのが好きではありません
Greg

1
GroupBoxをその方法で独自に拡張できますか?その場合は、レイアウトを壊している要素が見つかるまで、親要素を1つずつ追加していきます。
Drew Noakes、

RoBorg:知ってよかった、それで私は困惑しました、ありがとう
Edward Tanguay

1
ありがとう。あなたの答えを使用して、私は2つのネストされたDockPanelを使用して非常に類似した問題を解決することができました
Yablargo 2017

回答:


344

StackPanel最後の要素が残りのスペースをすべて使い果たすようにしたいようです。しかし、なぜ使用しないのDockPanelですか?で他の要素を装飾するDockPanelDockPanel.Dock="Top"、ヘルプコントロールで残りのスペースを埋めることができます。

XAML:

<DockPanel Width="200" Height="200" Background="PowderBlue">
    <TextBlock DockPanel.Dock="Top">Something</TextBlock>
    <TextBlock DockPanel.Dock="Top">Something else</TextBlock>
    <DockPanel
        HorizontalAlignment="Stretch" 
        VerticalAlignment="Stretch" 
        Height="Auto" 
        Margin="10">

      <GroupBox 
        DockPanel.Dock="Right" 
        Header="Help" 
        Width="100" 
        Background="Beige" 
        VerticalAlignment="Stretch" 
        VerticalContentAlignment="Stretch" 
        Height="Auto">
        <TextBlock Text="This is the help that is available on the news screen." 
                   TextWrapping="Wrap" />
     </GroupBox>

      <StackPanel DockPanel.Dock="Left" Margin="10" 
           Width="Auto" HorizontalAlignment="Stretch">
          <TextBlock Text="Here is the news that should wrap around." 
                     TextWrapping="Wrap"/>
      </StackPanel>
    </DockPanel>
</DockPanel>

DockPanel利用できないプラットフォーム(WindowsStoreなど)を使用している場合は、グリッドで同じ効果を作成できます。代わりにグリッドを使用して実行した上記の例を次に示します。

<Grid Width="200" Height="200" Background="PowderBlue">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="0">
        <TextBlock>Something</TextBlock>
        <TextBlock>Something else</TextBlock>
    </StackPanel>
    <Grid Height="Auto" Grid.Row="1" Margin="10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="100"/>
        </Grid.ColumnDefinitions>
        <GroupBox
            Width="100"
            Height="Auto"
            Grid.Column="1"
            Background="Beige"
            Header="Help">
            <TextBlock Text="This is the help that is available on the news screen." 
              TextWrapping="Wrap"/>
        </GroupBox>
        <StackPanel Width="Auto" Margin="10" DockPanel.Dock="Left">
            <TextBlock Text="Here is the news that should wrap around." 
              TextWrapping="Wrap"/>
        </StackPanel>
    </Grid>
</Grid>

18
鮮やかさ!StackPanelでこれを行う方法を理解するために、過去1時間を費やしました。これからは、まずWPF(およびその他の)情報をここで確認します。
paxdiablo

7
StackPanelsに自分のやりたいことをさせるために費やした時間を信じられません。共有してくれてありがとう!DockPanelsはずっとずっと欲しかったものです。
danglund 2012

タブレット用のドックパネルはないようです。telerik.com/forums/following-blog-post-and-comparison
JP Hellemons 2014

1
Windowsストアアプリのドックパネルはありません。
Teoman Shipahi 2014

ユニバーサルアプリがすべてで、ユニバーサルアプリはまだDockPanelをサポートしていませんか?
yonexbat 2016

105

これが発生している理由は、スタックパネルが、要素を積み上げる軸の制約として、正の無限大のすべての子要素を測定するためです。子コントロールは、必要な大きさを返す必要があります(正の無限大は、いずれかの軸のMeasureOverrideからの有効な戻り値ではありません)。これにより、すべてが収まる最小サイズを返します。彼らは実際にどのくらいのスペースを埋めなければならないかを知る方法がありません。

ビューにスクロール機能が必要なく、上記の回答がニーズに合わない場合は、独自のパネルを実装することをお勧めします。おそらくStackPanelから直接派生させることができ、ArrangeOverrideメソッドを変更して、残りのスペースを子要素間で分割する(それぞれに同じ量の余分なスペースを与える)だけです。必要以上のスペースが与えられた場合、要素は正常にレンダリングされるはずですが、要素を少なくすると、不具合が発生し始めます。

全体をスクロールできるようにしたい場合は、ScrollViewerが無制限に作業できるスペースを提供し、子要素と同じ位置に配置できるため、かなり難しいと思います。もともと。この状況では、新しいパネルにビューポートサイズを指定できる新しいプロパティを作成することができます。これをScrollViewerのサイズにバインドできるはずです。理想的にはIScrollInfoを実装しますが、すべてを適切に実装しようとすると複雑になります。


+1、1つだけ許可されますが、最初の段落では、多数のMicrosoftページが失敗したこと、つまり、高さ/幅として無限が発生する理由と、MeasureOverrideからavailableSizeを返すことに依存できないという事実を指摘しました。
エイダン

グリッド内のStackPanelは、彼のかなり一般的なニーズを非常に簡単に解決します。必要に応じて、一番下のビットをScrollViewer内に配置できます。私は2006年以来WPFを行っており、カスタムパネルを行う必要があったのは一度だけです。余分な複雑さを奨励することは良い考えではないと思います。
Chris Bordeman

@ChrisBordemanグリッド内のスタックパネルが問題をどのように解決するか理解できません。スタックパネルの1つ以上の子要素を伸ばして、利用可能なスペースを埋めるのが目的です。スタックパネルをグリッド内に配置しても、そうはなりませんか?
Caleb Vear

61

別の方法は、1列とn行のグリッドを使用することです。すべての行の高さをAutoに、一番下の行の高さをに設定し1*ます。

グリッドのレイアウトパフォーマンスはDockPanels、StackPanels、WrapPanelsよりも優れているため、この方法を選択します。ただし、それらをItemTemplate(レイアウトが多数のアイテムに対して実行されている)で使用しない限り、おそらく気付かないでしょう。


1
私にとって最良の解決策。これにより、複数の成長する行を定義することが可能になります
niyou

18

SpicyTaco.AutoGrid-の修正バージョンを使用できますStackPanel

<st:StackPanel Orientation="Horizontal" MarginBetweenChildren="10" Margin="10">
   <Button Content="Info" HorizontalAlignment="Left" st:StackPanel.Fill="Fill"/>
   <Button Content="Cancel"/>
   <Button Content="Save"/>
</st:StackPanel>

最初のボタンが塗りつぶされます。

NuGet経由でインストールできます。

Install-Package SpicyTaco.AutoGrid

SpicyTaco.AutoGridをご覧になることをお勧めします。これは、代わりにWPFのフォームのために非常に便利ですDockPanelStackPanelGrid非常に簡単かつ優雅にストレッチして問題を解決します。GitHubのreadmeをご覧ください。

<st:AutoGrid Columns="160,*" ChildMargin="3">
    <Label Content="Name:"/>
    <TextBox/>

    <Label Content="E-Mail:"/>
    <TextBox/>

    <Label Content="Comment:"/>
    <TextBox/>
</st:AutoGrid>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.