【问题标题】:Stick to bottom of grid in an inner ContentControl坚持内部 ContentControl 中的网格底部
【发布时间】:2020-03-25 12:24:06
【问题描述】:

我有一个主视图,里面有一个辅助子视图ChildViewModel

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

ChildViewModel 包含另一个元素网格,底部有一个由两个按钮组成的堆栈面板。我希望这两个按钮粘在整个窗口的底部。

我已经尝试过this 方法,但是由于整个内容控件位于底部(顶部有一个大的白色间隙),或者按钮位于内容控件的底部,因此它并不完全有效,但内容控件本身不在底部。

下图应该直观地解释我的意思。按钮是我想要在底部的两个小矩形。

编辑: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>

【问题讨论】:

  • “我想要的”并不完全是坚持。您能否显示ChildViewModel 的数据模板内容(因为必须在此处添加所需的空白)?另一件事不清楚是什么定义了空白的高度,你在“我想要什么”中有两个这样的,它们是如何分配可用空间的?如果您只想拉下其他居中控件的边框,那么您需要以某种方式参考原始高度。实现它的简单方法是在可视化树的同一级别上有另一个网格(通常在所有内容后面)。然后你可以将其他控件绑定到它的实际大小。
  • 我现在将添加内容控件的代码。至于空白的大小,它应该是可变的,因为元素的添加/删除取决于用户的操作。内容控件本身的大小会发生变化,并且可以占据窗口的全部空间。我想拉下边界是我想要的。窗口本身的大小是固定的,因此可能会更容易。创建一个改变大小的网格可能是解决方案。
  • 问题是两个测量通道:一个是在第一张图片上获取内容控件的大小,另一个是实际居中并拉下边框。如果您可以在可视树中使用两次(我对此表示怀疑,第一个可以重叠和禁用,但仍然可以),然后在上面加倍 xaml,从倒数第二行删除并将第一个空行的高度绑定到实际高度从第一行开始的任何星行。然后在内容控件中添加星行,它应该可以工作。

标签: c# wpf


【解决方案1】:

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

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

【讨论】:

  • 你能张贴一张你所做的照片或更好的 GIF 吗?顺便说一句,&lt;RowDefinition Height="*" /&gt; 就是 &lt;RowDefinition /&gt;
  • 我刚刚意识到我的代码中有一个错误,并且孩子中的RowDefinitions 都是自动的(现在已编辑)。我不太明白代码中的行定义中发生了什么。你能解释一下吗:) 编辑:它似乎确实有效(有一些细微的变化)!我不需要把它们都写成*,只需要中间几行。
  • 我更新了我的答案以解决您的新行大小问题。如果控件中的所有行都是自动调整大小的,那么只需使用堆栈面板。一般会轻松一些。但是,您仍然希望将最后一行设为星号大小(占用所有可用空间)。
猜你喜欢
  • 2015-06-24
  • 1970-01-01
  • 2021-01-18
  • 2015-04-21
  • 2020-01-28
  • 2014-02-02
  • 1970-01-01
  • 1970-01-01
  • 2020-06-16
相关资源
最近更新 更多