Xamarin:向网格动态添加行时的大小调整问题

Xamarin: Sizing Issues when dynamically adding rows to a Grid

我是 Xamarin 的新手,我正在尝试了解一些基本功能。

我有一个简单的内容页面,其中包含一个带有嵌套 StackLayout 的 ScrollView,然后是 StackLayout 中的其他嵌套控件:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="TestApp.Views.ScrollGrow">

  <ScrollView x:Name="myScrollView" BackgroundColor="LightBlue" VerticalOptions="FillAndExpand">
    <StackLayout x:Name="MainStack" BackgroundColor="YellowGreen" VerticalOptions="FillAndExpand">
        <Label Text="Start of StackLayout"></Label>
        <Button Text="Populate Grid" Clicked="Button_Clicked" x:Name="btnFill" BackgroundColor="Black" TextColor="White"></Button>
        <Grid x:Name="myGrid" BackgroundColor="Yellow" VerticalOptions="FillAndExpand"></Grid>
        <Label Text="Bottom of StackLayout"></Label>
    </StackLayout>
  </ScrollView>
</ContentPage>

我正在尝试通过单击按钮将行动态添加到网格:

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace TestApp.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ScrollGrow : ContentPage
{

    public ScrollGrow()
    {
        InitializeComponent();
    }

    private void Button_Clicked(object sender, EventArgs e)
    {
        Device.BeginInvokeOnMainThread(() =>
        {
            for (int i = 0; i <= 35; i++)
            {
                FillMyGrid(i);
            }               
        });
    }

    private void FillMyGrid(int theCounter)
    {
        myGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto, });
        var testLabel = new Label();
        testLabel.Text = "Test row number: " + theCounter;
        testLabel.TextColor = Color.Black;
        Grid.SetRow(testLabel, theCounter);
        Grid.SetColumn(testLabel, 0);
        myGrid.Children.Add(testLabel);
    }

  }
}

不幸的是,StackLayout 的大小并没有随着 Grid 的增长而增长。

Before After

我在这里错过了什么?有人可以向我解释为什么这不起作用以及正确的方法是什么吗?

我建议像这样重新排列您的 UI(使用 Grid)。

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

    <Label Grid.Row="0" Text="Start of StackLayout"></Label>
    <Button Grid.Row="1" Text="Populate Grid" Clicked="Button_Clicked" x:Name="btnFill" BackgroundColor="Black" TextColor="White"></Button>

    <ScrollView Grid.Row="2">
        <Grid x:Name="myGrid" BackgroundColor="Yellow"></Grid>
    </ScrollView>

    <Label Grid.Row="3" Text="Bottom of StackLayout"></Label>
</Grid>

此外,要显示重复数据,最好使用 ListView

StackLayouts 可能有点令人困惑。对于垂直方向的 StackLayout 的子级,任何扩展请求(即 VerticalOptions="FillAndExpand")都将被忽略,因为 StackLayout 本身正在确定每个子级的大小,因此自身的大小是所有子级加上的总和任何间距和填充。

,显示重复数据时最好使用ListView。我还鼓励您在网格中非常谨慎地使用 Auto,因为在布局更改时计算行高会带来额外的负担。如果您更愿意继续使用网格,我建议您对行使用 *(星号)单位以确保它们的大小相对于彼此,或者设置一个静态行高,然后向上冒泡StackLayout 的计算高度。

在ScrollView之外使用StackLayout可能会达到你想要的效果。

这里是 xaml 代码:

<StackLayout>
    <ScrollView x:Name="myScrollView" BackgroundColor="LightBlue" VerticalOptions="FillAndExpand">
        <StackLayout x:Name="MainStack" BackgroundColor="YellowGreen" VerticalOptions="FillAndExpand">
            <Label Text="Start of StackLayout"></Label>
            <Button Text="Populate Grid" Clicked="btnFill_Clicked"  x:Name="btnFill" BackgroundColor="Black" TextColor="White"></Button>
            <Grid x:Name="myGrid" BackgroundColor="Yellow" VerticalOptions="FillAndExpand"></Grid>
            <Label Text="Bottom of StackLayout"></Label>
        </StackLayout>
    </ScrollView>
</StackLayout>

截图如下: