web-dev-qa-db-ja.com

StackPanelの子に最大スペースを下方に埋める方法は?

私は単に左側にテキストを流し、右側にヘルプボックスを入れたいだけです。

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

下の外側のStackPanelを取り出すと、うまく機能します。

しかし、レイアウト上の理由から(私は動的にUserControlを挿入しています)、ラッピング用のStackPanelが必要です。

GroupBoxをStackPanelの一番下まで拡張するにはどうすればよいですか。

  • VerticalAlignment = "Stretch"
  • VerticalContentAlignment = "ストレッチ"
  • 高さ= "自動"

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>

回答:

Markさん、StackPanelの代わりにDockPanelを使用することで解決しました。一般的に、私は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>
325
Edward Tanguay

最後の要素が残りのスペースをすべて使い果たしたStackPanelが欲しいようですね。しかし、なぜDockPanelを使わないのですか? DockPanel内の他の要素をDockPanel.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>
312
Mark Heath

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

あなたの見解がスクロール機能を持​​つ必要がなく、上記の答えがあなたのニーズに合わない場合、私はあなた自身のパネルを実装することをお勧めします。あなたはおそらくStackPanelから直接派生することができます、それからあなたがする必要があるのはそれがその子要素間の残りのスペースを分割するように ArrangeOverride メソッドを変更することです(それぞれに同じ量の追加スペースを割り当てます)。要素に必要以上のスペースが与えられている場合、要素はうまくレンダリングされるはずですが、要素を少なくすると、グリッチが見え始めます。

ScrollViewerを使用すると、無限のスペースを使用して子要素と同じ位置に移動できるため、全体をスクロールできるようにするには、物事がかなり難しくなります。もともと。このような場合は、新しいパネルにビューポートのサイズを指定できる新しいプロパティを作成することをお勧めします。これをScrollViewerのサイズにバインドできるはずです。理想的には IScrollInfo を実装しますが、それをすべて正しく実装しようとすると複雑になり始めます。

101
Caleb Vear

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

DockPanel、StackPanel、およびWrapPanelよりもGridの方がレイアウトパフォーマンスが優れていることがわかったため、この方法が適しています。しかし、ItemTemplateでそれらを使用していない限り(レイアウトが多数の項目に対して実行されている場合)、おそらく気付かないでしょう。

56
rcabr

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

私はまた wpf-autogrid を見てみることをお勧めします。 DockPanel、StackPanel、およびGridの代わりにWPFのフォームに非常に役立ち、非常に簡単で優雅にストレッチを行うことで問題を解決します。 githubのreadmeを見てください。

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

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

    <Label Content="Comment:"/>
    <TextBox/>
</st:AutoGrid>
14
Dvor_nik