首页 > 解决方案 > Stick to bottom of grid in an inner ContentControl

问题描述

I have a main view with a secondary child view ChildViewModel inside it:

<Window {...}>
  <Window.Resources> {...} </Window.Resources>

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

    <Grid Grid.Row="0"> {...} </Grid>

    <StackPanel Grid.Row="1"> {...} </StackPanel>

    <ContentControl Grid.Row="2"
                    Content="{Binding ChildViewModel}"/>

  </Grid>
</Window>

The ChildViewModel contains another grid of elements, with a Stack Panel of two buttons at the bottom. I would like these two buttons to be stuck to the bottom of the whole window.

I have tried this method, however it doesn't quite work as either the whole content control is at the bottom (with a large white gap at the top), or the buttons are at the bottom of the content control, but the content control itself is not at the bottom.

The following image should explain visually what I mean. The buttons are the two small rectangles that I would like at the bottom.

EDIT: Code of the Content Control:

  <UserControl {..}>
  <UserControl.DataContext>
    <viewModels:ChildViewModel />
  </UserControl.DataContext>

  <Grid FocusVisualStyle="{x:Null}">
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Grid.Resources>
      {..}
    </Grid.Resources>

    <ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto" FocusVisualStyle="{x:Null}"> 
    {..}
    </ScrollViewer>

    <customViews:SwirlyThingy Grid.Row="1" {..}/>

    <TextBlock Grid.Row="2" {..}/>

    <TextBlock Grid.Row="3" {..}/>

    <TextBlock Grid.Row="4" {..}}"/>

    <!--The buttons I'd like at the bottom-->
    <StackPanel Grid.Row=5"
                VerticalAlignment="Bottom"
                Orientation="Horizontal"
                misc:MarginSetter.Margin="6">
      <Button Command="{Binding PrepareForMigrationCommand}"
              IsEnabled="{Binding CanMigrate,
                                   UpdateSourceTrigger=PropertyChanged}">
        <Button.Style>
          <Style BasedOn="{StaticResource MajorControlButton}" TargetType="Button">
            <Setter Property="Content" Value="Migrate" />
            <Style.Triggers>
              <DataTrigger Binding="{Binding PrepareForMigrationCommand.Execution.IsNotCompleted}"
                           Value="True">
                <Setter Property="Content" Value="Migrating..." />
              </DataTrigger>
            </Style.Triggers>
          </Style>
        </Button.Style>
      </Button>
      <Button Command="{Binding PrepareForMultiMigrationCommand}"
              Visibility="{Binding IsMultiMigration,
                                    UpdateSourceTrigger=PropertyChanged,
                                    Converter={StaticResource BooleanToVisibilityConverter}}">
        <Button.Style>
          <Style BasedOn="{StaticResource MajorControlButton}" TargetType="Button">
            <Setter Property="Content" Value="Run All" />
          </Style>
        </Button.Style>
      </Button>

    </StackPanel>
  </Grid>
</UserControl>

image of how I'd like the format to be

标签: c#wpf

解决方案


您想为最后一项占用所有可用空间。为了做到这一点,您将在您的顶级网格的最后一行按星标大小。

<Grid.RowDefinitions>
  <RowDefinition Height="Auto" />
  <RowDefinition Height="Auto" />
  <RowDefinition Height="*" />    <!-- Star size this one -->
</Grid.RowDefinitions>

在您的控制中,您可以简单地拥有两行,一行用于包含在堆栈面板中的所有内容(而不是多行)。你的按钮有一排。您的按钮面板将与底部对齐

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

    <Grid Grid.Row="0">
        <Rectangle Height="20" Fill="Red"/>
    </Grid>

    <StackPanel Grid.Row="1">
        <Rectangle Height="20" Fill="Orange"/>
        <Rectangle Height="20" Fill="Yellow"/>
        <Rectangle Height="20" Fill="Green"/>
    </StackPanel>

    <Grid Grid.Row="2"> <!-- simulating your custom control -->
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <StackPanel Grid.Row="0">
            <!-- A bunch of content here
        </StackPanel>

        <StackPanel Grid.Row="1"
                    Orientation="Horizontal"
                    VerticalAlignment="Bottom">
            <Button Content="Click Me!"/>
            <Button Content="No, Me!"/>
        </StackPanel>
    </Grid>
</Grid>

推荐阅读