说我有一个显示为网格布局的项目列表。每个项目占一行,由一列中的多个项目组成。基本上是一张桌子:
<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>
每个标签/图像代表我要显示的项目列表中的一行。我暂时不担心数据绑定,我只想将Label / Image移动到自定义控件中,以便可以使用该自定义控件将“行”添加到我的网格中:
<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>
我可能可以从我的自定义控件中将Lable / Image / etc设置为后面代码中的适当行/列。我迷路的地方是应该使用哪种类型的基类进行此自定义控件?因为是该类将成为Grid的内容,而不是Labels和Images,所以Grid.Row和Grid.Column将无法正确传播。我真的希望我能对此做出解释。
我可以在Xamarin中创建一个自定义控件,将其作为内容添加到Grid中,让其子级尊重Grid的列吗?
答案 0 :(得分:0)
您可以这样写
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;
}
}