Xamarin.Forms 将自定义控件创建为网格布局中的一行
Posted
技术标签:
【中文标题】Xamarin.Forms 将自定义控件创建为网格布局中的一行【英文标题】:Xamarin.Forms create a custom control as a row in a Grid layout 【发布时间】:2019-08-16 11:47:18 【问题描述】:假设我有一个显示为网格布局的项目列表。每个项目占一行,由一列中的多个项目组成。它基本上是一张桌子:
<Grid>
<Label Text="Item1" Grid.Row="0" Grid.Colum="0" />
<Image Src="something1" Grid.Row="0" Grid.Colum="1" />
<Label Text="Item2" Grid.Row="1" Grid.Colum="0" />
<Image Src="something2" Grid.Row="1" Grid.Colum="1" />
<Label Text="Item3" Grid.Row="2" Grid.Colum="0" />
<Image Src="something3" Grid.Row="2" Grid.Colum="1" />
</Grid>
每个标签/图像代表我要显示的项目列表中的一行。我暂时不担心数据绑定,我只想将标签/图像移动到自定义控件中,以便可以使用该自定义控件将“行”添加到我的网格中:
<Grid>
<customcontrol:MyCustomRowControl Text="Item1" Source="img1" Grid.Row="0"/>
<customcontrol:MyCustomRowControl Text="Item2" Source="img1" Grid.Row="1"/>
<customcontrol:MyCustomRowControl Text="Item3" Source="img1" Grid.Row="3"/>
</Grid>
我可能可以将自定义控件中的标签/图像/等设置为代码隐藏中的适当行/列。我迷失的是我应该制作这个自定义控件的基类类型是什么?因为将成为 Grid 内容的是该类,而不是 Labels 和 Images,因此 Grid.Row 和 Grid.Column 不会正确传播。我真的希望我设法解释了这一点。
我可以在 Xamarin 中创建一个自定义控件,我可以将它作为内容添加到 Grid 并让它的子项尊重 Grid 的列吗?
【问题讨论】:
如果我理解正确,您可以将其设为具有两列的Grid
,第 0 列是 Label
,第 1 列是 Image
。然后使用 customcontrol
和 ColumnSpan=2
嗯,是的,这将编译,但列不会在项目之间均衡。每个标签都有自己的宽度,所以表格基本上会被破坏
您是否希望所有标签的宽度都为最宽的Label
?否则,您可以使用固定宽度(* 而不是 ColumnDefinitions 中的 Auto)
是的,我在 Auto 上有一些列,我希望这些列宽在所有行上传播,本质上是创建一个表
你能测试我的代码吗? @Radu094
【参考方案1】:
你可以这样写
DynamicGridView 类
public class DynamicGridView : Grid
private int _rowCount;
private int _columnCount;
protected int _column;
protected int _starHeight = 0;
protected int _type;
protected int[] _starHeightList;
public DynamicGridEnum _dynamicGridEnum;
public DynamicGridView(DynamicGridEnum dynamicGridEnum, params int[] starHeightList)
_type = 2;
switch (dynamicGridEnum)
case DynamicGridEnum.Auto:
_column = starHeightList[0];
break;
case DynamicGridEnum.Star:
_column = starHeightList[0];
_starHeight = starHeightList[1];
_type = 1;
break;
case DynamicGridEnum.Custom:
_column = starHeightList.Length;
break;
default:
break;
_starHeightList = starHeightList;
_dynamicGridEnum = dynamicGridEnum;
_rowCount = 0;
_columnCount = 0;
Padding = 0;
Margin = 0;
ColumnSpacing = -1;
RowSpacing = -1;
public virtual void AddView(View view)
int countRow = _rowCount / _column;
if (RowDefinitions.Count <= countRow)
RowDefinitions.Add(new RowDefinition() Height = new GridLength(1, (GridUnitType)_type) );
Children.Add(view, _columnCount, countRow);
_rowCount++;
_columnCount++;
_columnCount = _columnCount % _column;
DynamicGrid 类
public class DynamicGrid : DynamicGridView
public DynamicGrid(DynamicGridEnum dynamicGridEnum, params int[] starHeightList) : base(dynamicGridEnum, starHeightList)
for (int i = 0; i < starHeightList.Length; i++) starHeightList[i] = starHeightList[i] <= 0 ? 1 : starHeightList[i];
if (dynamicGridEnum == DynamicGridEnum.Custom)
StartCustomGrid();
else
StartGrid();
private void StartGrid()
int percent = 100 / _column;
for (int i = 0; i < _column; i++)
ColumnDefinitions.Add(new ColumnDefinition() Width = new GridLength(percent, (GridUnitType)_type) );
private void StartCustomGrid()
foreach (var item in _starHeightList)
ColumnDefinitions.Add(new ColumnDefinition() Width = new GridLength(item, GridUnitType.Star) );
以及动态网格的使用(我为网格类型定义了一个枚举。对于 例如,如果枚举是自动的,它将自动调整网格的行/列。)
public partial class MainPage : ContentPage
public MainPage()
StackLayout sl = new StackLayout();
DynamicGrid dynamicGrid = new DynamicGrid(Enums.DynamicGridEnum.Custom, 20, 50, 20, 0);
dynamicGrid.AddView(new BoxView() BackgroundColor = Color.AliceBlue );
dynamicGrid.AddView(new BoxView() BackgroundColor = Color.Aqua );
dynamicGrid.AddView(new BoxView() BackgroundColor = Color.AntiqueWhite );
dynamicGrid.AddView(new BoxView() BackgroundColor = Color.Azure );
sl.Children.Add(new CardView(Color.Beige, Color.Bisque, 60, Color.Black, 90, 10));
sl.Children.Add(dynamicGrid);
Content = sl;
【讨论】:
以上是关于Xamarin.Forms 将自定义控件创建为网格布局中的一行的主要内容,如果未能解决你的问题,请参考以下文章
如何创建一个自定义控件,用户可以在 Xamarin.Forms 中添加任何类型的视图?
自定义控件的 Xamarin 数据绑定值计算为 Xamarin.Forms.Binding
Xamarin.Forms自定义用户界面控件实现一个HybridWebView(混合webview)