Xamarin.Forms将自定义控件创建为Grid布局中的一行

时间:2019-03-26 06:51:00

标签: xamarin.forms

说我有一个显示为网格布局的项目列表。每个项目占一行,由一列中的多个项目组成。基本上是一张桌子:

<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的列吗?

1 个答案:

答案 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;
}
}