Как заставить дочерние элементы StackPanel заполнить максимальное пространство вниз?

StackOverflow https://stackoverflow.com/questions/569095

Вопрос

Мне просто нужен плавный текст слева и окно помощи справа.

Поле помощи должно доходить до самого низа.

Если вы уберете внешнюю StackPanel ниже, она будет работать отлично.

Но по соображениям макета (я вставляю UserControls динамически) мне нужна оболочка StackPanel.

Как мне расширить GroupBox до нижней части StackPanel, как вы можете видеть, я пробовал:

  • ВертикальноеВыравнивание="Растянуть"
  • ВертикальныйКонтентАлинмент="Растянуть"
  • Высота="Авто"

КСАМЛ:

<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>
Это было полезно?

Решение

Похоже, ты хочешь StackPanel где последний элемент занимает все оставшееся пространство.Но почему бы не использовать DockPanel?Украсьте другие элементы в DockPanel с DockPanel.Dock="Top", и тогда ваш элемент управления помощью сможет заполнить оставшееся пространство.

КСАМЛ:

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

Другие советы

Причина, по которой это происходит, заключается в том, что панель стека измеряет каждый дочерний элемент с положительной бесконечностью в качестве ограничения для оси, вдоль которой она укладывает элементы.Дочерние элементы управления должны возвращать желаемый размер (положительная бесконечность не является допустимым возвратом из Измерить переопределение по любой оси), поэтому они возвращают наименьший размер, в котором все поместится.У них нет возможности узнать, сколько места им действительно нужно заполнить.

Если вашему представлению не требуется функция прокрутки и приведенный выше ответ не соответствует вашим потребностям, я бы предложил реализовать собственную панель.Вероятно, вы можете получить результат прямо из StackPanel, и тогда все, что вам нужно будет сделать, это изменить УпорядочитьOverride метод так, чтобы он делил оставшееся пространство между своими дочерними элементами (давая каждому одинаковое количество дополнительного пространства).Элементы должны отображаться нормально, если им предоставлено больше места, чем им хотелось, но если вы дадите им меньше, вы начнете видеть сбои.

Если вы хотите иметь возможность прокручивать все это, то, боюсь, все будет немного сложнее, потому что ScrollViewer дает вам бесконечное количество пространства для работы, которое поместит вас в то же положение, в котором были дочерние элементы. изначально.В этой ситуации вы можете захотеть создать на новой панели новое свойство, которое позволит вам указать размер области просмотра. У вас должна быть возможность привязать его к размеру ScrollViewer.В идеале вы бы реализовали IScrollInfo, но это начинает усложняться, если вы собираетесь реализовать все это правильно.

Альтернативный метод — использовать Grid с одним столбцом и н ряды.Установите высоту всех строк на Auto, и высота самой нижней строки до 1*.

Я предпочитаю этот метод, поскольку обнаружил, что Grids обеспечивает лучшую производительность макета, чем DockPanels, StackPanels и WrapPanels.Но если вы не используете их в ItemTemplate (где макет выполняется для большого количества элементов), вы, вероятно, никогда этого не заметите.

Вы можете использовать модифицированная версия из 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-автосетка.Это очень полезно для форм в WPF вместо DockPanel, StackPanel и Grid и очень легко и изящно решает проблемы с растяжением.Просто посмотрите readme на github.

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

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

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

Несколько вещей, которые вы могли бы сделать:

1:Установить Orientation к Вертикальный:

<StackPanel Orientation="Vertical"></StackPanel>
  1. Установить Height принадлежащий StackPanel то же, что и у окна:

И, конечно же, вы можете комбинировать эти Характеристики:

<StackPanel Orientation="Vertical" Height="600"></StackPanel>

Вам не нужно выполнять кучу дополнительной работы по установке NuGets и тому подобному....

РЕДАКТИРОВАТЬ

Вы также можете разместить StackPanel внутри ScrollViewer.Это позволит вам контролировать высоту GroupBox, не жертвуя видимостью содержимого.

<GroupBox>
    <ScrollViewer>
        <StackPanel Orientation="Vertical>
              <!-- Place Children Objects here-->
        <StackPanel>
    <ScrollViewer>
<GroupBox>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top