Xamarin.Forms:如何在Grid指定列(索引1)动态添加子控件
问题:Xamarin.Forms Grid动态替换指定列控件时,新控件跑到第0列怎么办?
先看你给出的Grid布局XAML代码:
<Grid Grid.Row="5" x:Name="row5_piccat"> <Grid.ColumnDefinitions > <ColumnDefinition Width="*"/> <ColumnDefinition Width="4*" /> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <ImageButton Aspect="AspectFit" x:Name="btn_dummy_piccat2" Grid.Column="1" Source="btn_emptydummy.png" BackgroundColor="#00000000"/> <Entry x:Name="entry_descri_pickcate" Grid.Column="1" FontFamily="arial" MaxLength="50" Placeholder="Kurzbeschreibung" BackgroundColor="#00000000" TextColor="#272727" HorizontalOptions="Center" VerticalOptions="Center"> </Entry> </Grid>
你的需求是把第1列(索引1)里的ImageButton和Entry替换成红色BoxView,但写的代码里新控件总是出现在第0列,原代码如下:
private void SetLayoutForTakers() { btn_dummy_piccat2.IsVisible = false; entry_descri_pickcate.IsVisible = false; Grid grid = new Grid(); //Neues Grid BoxView bx = new BoxView(); bx.Color = Xamarin.Forms.Color.Red; grid.Children.Add(bx); row5_piccat.Children.Add(grid); }
问题根源
你添加新的嵌套Grid时,没有指定它在父Grid中的列位置。Xamarin.Forms Grid的子控件默认会放在Column=0的位置,所以你的新Grid才会跑到第0列去。另外,仅仅隐藏旧控件而不移除,这些控件依然存在于Grid的子集合中,虽然看不见但还是占着资源,不是最优解。
两种正确的解决方式
方式1:直接添加BoxView到目标列(推荐,更简洁)
直接创建BoxView并指定它的列位置,同时移除旧控件:
private void SetLayoutForTakers() { // 筛选出第1列的所有旧控件并移除 var oldColumnControls = row5_piccat.Children .Where(control => Grid.GetColumn(control) == 1) .ToList(); foreach (var control in oldColumnControls) { row5_piccat.Children.Remove(control); } // 创建红色BoxView BoxView redBox = new BoxView { Color = Xamarin.Forms.Color.Red }; // 关键:指定BoxView在父Grid的第1列(行默认是0) Grid.SetColumn(redBox, 1); // 添加到父Grid中 row5_piccat.Children.Add(redBox); }
方式2:如果需要嵌套Grid,记得设置嵌套Grid的列位置
如果你确实需要把BoxView放在新的嵌套Grid里,一定要给这个嵌套Grid设置Grid.Column属性:
private void SetLayoutForTakers() { // 移除旧控件(替代隐藏的更优做法) var oldColumnControls = row5_piccat.Children .Where(control => Grid.GetColumn(control) == 1) .ToList(); foreach (var control in oldColumnControls) { row5_piccat.Children.Remove(control); } // 创建嵌套Grid和BoxView Grid nestedGrid = new Grid(); BoxView redBox = new BoxView { Color = Xamarin.Forms.Color.Red }; nestedGrid.Children.Add(redBox); // 关键:指定嵌套Grid在父Grid的第1列 Grid.SetColumn(nestedGrid, 1); // 添加到父Grid row5_piccat.Children.Add(nestedGrid); }
补充说明
把旧控件从Grid的Children集合中移除,相比仅仅设置IsVisible=false,能避免不必要的内存占用,也不会出现控件堆叠可能导致的意外交互问题,是更干净的实现方式。
内容的提问来源于stack exchange,提问作者innomotion media
相关产品推荐
相关产品推荐

