【问题标题】:Xamarin.Forms Insert Row to Grid and re-arrangeXamarin.Forms 将行插入网格并重新排列
【发布时间】:2025-11-27 18:15:02
【问题描述】:

我正在尝试将新对象插入到第 0 行的现有网格中(将剩余的行向下移动一格)。有没有办法做到这一点?与 Log 类似,最后一项位于第一位。请注意,我不能使用 ListView,我已经在内容中有一个。另外,我更喜欢使用 Grid,因为我可以更好地构建它以进行演示等。 完成的网格结构:

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

> <Grid.ColumnDefinitions>
>      <ColumnDefinition/>
>      <ColumnDefinition/>
>      <ColumnDefinition/>  
</Grid.ColumnDefinitions>
> (existing Labels)
> <Label Text="1" Grid.Column="0" Grid.Row="0"/> 
<Label Text="2" Grid.Column="0" Grid.Row="0"/> 
> <Label Text="3", Grid.Column="0", Grid.Row="0"/>
>  </>

我正在以编程方式生成网格,以填写上述结构(迭代列/行 nr),然后尝试使用 Child 插入顶行:

MyGrid.RowDefinitions.Insert(0,newDefinition); // Insert new row

               

>  MyGrid.Children.Add(new Label
>                         {
>               Text = "original row",
>                             TextColor = Color.Black,
>                             LineBreakMode = Xamarin.Forms.LineBreakMode.WordWrap,
>                             HorizontalTextAlignment = TextAlignment.End,
>                             FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
>                         }, 0, 0); //Column / Row

...

> MyGrid.RowDefinitions.Insert(0,newDefinition); // Insert new row
> at 0 row index
> 
> 
>                         MyGrid.Children.Add(new Label
>                         {
>               Text = "new row",
>                             TextColor = Color.Black,
>                             LineBreakMode = Xamarin.Forms.LineBreakMode.WordWrap,
>                             HorizontalTextAlignment = TextAlignment.End,
>                             FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
>                         }, 0, 0); //Column / Row

“新行”将与“原行”重叠

编辑: 到目前为止,这就是我所做的。这仅适用于一次行移位,没有列移位。

我无法通过 Grid Child 列/行获得

var left = Grid.Children[0].Left();//Experimental flag 所以我将不得不进行更多迭代。

...添加带有标签的新行,0 列(默认情况下,Grid 有 1 列,1 个网格),然后:

Grid.RowDefinitions.Add(newRow); 

for (int i = Grid.Children.Count -1 ; i >= 0; i--) 
{ 
     var child = > Grid.Children[i]; 
     Grid.Children.RemoveAt(i); 
     Grid.Children.Add(child, 0, i +1); 
} 
Grid.Children.Add(SomeLabel, 0, 0);

【问题讨论】:

    标签: c# xamarin.forms grid


    【解决方案1】:

    要将网格中的所有行移一格,可以使用Grid.GetRow()Grid.SetRow() 方法,如下面的示例代码。

    foreach (var child in grid.Children)
    {
        var row = Grid.GetRow(child);
        Grid.SetRow(child, row + 1);
    }
    

    【讨论】:

      【解决方案2】:

      你可以把你Label转成List,然后实现。

      例如,如果我想在第一行第二列的地方添加一个标签,这里是运行GIF。

      这是我的网格布局。

      <StackLayout Margin="10">
            
              <Button Text="add" Clicked="Button_Clicked"></Button>
              <Grid x:Name="MyGrid">
                <Grid.RowDefinitions>
                  <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                  <ColumnDefinition/>
                  <ColumnDefinition/>
                  <ColumnDefinition/>
              </Grid.ColumnDefinitions>
          </Grid>
      </StackLayout>
      

      这是我的布局背景代码。我在List 中添加三个Labels,然后将列表中的项目添加到Grid。单击按钮时,在第 0 行第 1 列添加一个新的Label,在列表视图中的位置为 1。

      public partial class MainPage : ContentPage
      {
          List<Label> labels;
      
          public MainPage()
          {
              InitializeComponent();
              labels = new List<Label>();
              labels.Add(new Label
              {
                  Text = "1",
                
                  LineBreakMode = Xamarin.Forms.LineBreakMode.WordWrap,
                  HorizontalTextAlignment = TextAlignment.End,
                  FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
              });
              labels.Add(new Label
              {
                  Text = "2",
      
                  LineBreakMode = Xamarin.Forms.LineBreakMode.WordWrap,
                  HorizontalTextAlignment = TextAlignment.End,
                  FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
              });
              labels.Add(new Label
              {
                  Text = "3",
      
                  LineBreakMode = Xamarin.Forms.LineBreakMode.WordWrap,
                  HorizontalTextAlignment = TextAlignment.End,
                  FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
              });
      
              for (int i=0; i<labels.Count ;i++)
              {
                  //If we set the three columns, we can set the Column and  Row by i%3 i/3
                  MyGrid.Children.Add(labels[i],i%3,i/3);
              }
          }
          
          private void Button_Clicked(object sender, EventArgs e)
          {
              // Remove the data in the original Gird
              for (int i = 0; i < labels.Count; i++)
              {
                  if (MyGrid.Children.Count>0)
                  {
                      var label = labels[i];
      
                      if (label != null)
                      {
                          MyGrid.Children.Remove(label) ;
                      }
                  }
              }
      
              // add label
              var newLabel = new Label
              {
                  Text = "new row",
                  TextColor = Color.Black,
                  LineBreakMode = Xamarin.Forms.LineBreakMode.WordWrap,
                  HorizontalTextAlignment = TextAlignment.End,
                  FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
              };
      
              // If I want add a label in the first row and second Column place, I can add the new label to with `Insert` method in List.
              labels.Insert(1,newLabel);
      
              // re-add the list data to grid.
              for (int i = 0; i < labels.Count; i++)
              {
                  MyGrid.Children.Add(labels[i], i % 3, i / 3);
              }
          }
      }
      

      【讨论】:

      • 谢谢大家,非常有帮助。