Чтобы добиться этого, вложите еще один Grid
в LayoutRoot
, а затем используйте эту вложенную сетку в качестве основной. Затем установите обе строки на Auto
.
<Grid x:Name="LayoutRoot" Background="White">
<Grid x:Name="innerGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid x:Name="itemInTheFirstRow" Grid.Row="0" />
<Button x:Name="itemInTheSecondRow" Grid.Row="1" />
</Grid>
</Grid>
Наконец, вам нужно отследить размер сетки и соответственно изменить правила определения размера. Этот код закрепления выглядит примерно так.
RowDefinition row = this.innerGrid.RowDefinitions[0];
if (row.Height.GridUnitType == GridUnitType.Auto)
{
if (this.innerGrid.ActualHeight > this.ActualHeight)
{
row.Height = new GridLength(1, GridUnitType.Star);
}
}
else
{
if (this.itemInTheFirstRow.DesiredSize.Height < row.ActualHeight)
{
row.Height = GridLength.Auto;
}
}
В моей реализации я обертываю этот код в метод UpdateRowPinning
, который фактически использует диспетчер для вызова этого кода. Затем я вызываю UpdateRowPinning
для событий изменения размера основной сетки и внутренней сетки, а также для добавления и удаления элементов из сетки и операций развертывания / сворачивания групп сетки. Это гарантирует, что второй ряд ведет себя должным образом, сидя у основания первого ряда до тех пор, пока экран не заполнится, а затем переместившись над ним.
Мой ответ здесь также охватывает эту проблему. Я искал решение только для XAML, но это просто не представляется возможным (если вы не напишете некоторые расширения XAML, тогда вы сможете реализовать его с XAML, но это обман).