在xamarin中创建自定义iOS控件

时间:2017-06-08 11:43:53

标签: c# ios xamarin xamarin.ios xamarin.forms

我在Xamarin项目中创建了一个自定义iOS控件。但是,当它在Xamarin.Forms页面上添加到XAML中时,它当前不会使用该页面。

<OnPlatform.iOS>
    <iOSControls:CellContent BindingContext="{Binding}" CellData="{Binding VM.CellCollection}"/>
</OnPlatform.iOS>

我也不确定这是否是将数据从ViewModel绑定到控件的正确方法,并且由于它没有加载我无法测试它。

CellContent类如下

   `Public partial class CellContent : UIView
    {

    #region [ Private Fields ]

    /// <summary>
    /// The cell data model used for generating each cell
    /// </summary>
    private ICell cellData;

    #endregion

    #region [ Constructor ]

    /// <summary>
    /// Initializes a new instance of the <see cref="CellContent" /> class.
    /// </summary>
    /// <param name="handle">handle pointer passed to the base class</param>
    public CellContent(IntPtr handle) : base(handle)
    {
    }

    #endregion

    #region [ Public Properties ]

    /// <summary>
    /// Gets or sets the cell data model
    /// </summary>
    [Export("CellData"), Browsable(true)]
    public ICell CellData
    {
        get
        {
            return this.cellData;
        }
        set
        {
            this.cellData = value;
        }
    }

    #endregion

    #region [ UIView Events ]

    /// <summary>
    /// Static control generator
    /// </summary>
    /// <returns>A control instance</returns>
    public static CellContent Create()
    {
        var arr = NSBundle.MainBundle.LoadNib("CellContent", null, null);
        var v = Runtime.GetNSObject<CellContent>(arr.ValueAt(0));

        return v;
    }

    /// <summary>
    /// Initialises the sub controls
    /// </summary>
    public override void AwakeFromNib()
    {
        base.AwakeFromNib();

        HorizontalGridLines horizontalRows = HorizontalGridLines.Create();
        VerticalGridLines verticalRows = VerticalGridLines.Create();
        PlottedActivity plottedActivity = PlottedActivity.Create();
        horizontalRows.VM = this.CellData;
        verticalRows.VM = this.CellData;
        plottedActivity.VM = this.CellData;

        this.AddSubview(horizontalRows);
        this.AddSubview(verticalRows);
        this.AddSubview(plottedActivity);
    }

    #endregion`

水平/垂直网格线和绘制的活动文件基本相同,我已经验证它们在单独的项目中工作(没有绑定或从XAML实例化),但是Horizo​​ntalGridLines文件也可以在下面看到供参考

`public partial class HorizontalGridLines : UIView
{
    /// <summary>
    /// Initializes a new instance of the <see cref="HorizontalGridLines" /> class.
    /// </summary>
    /// <param name="handle">handle pointer passed to the base class</param>
    public HorizontalGridLines(IntPtr handle) : base(handle)
    {
    }

    /// <summary>
    /// Gets or sets the data context cast as an interface for binding
    /// </summary>
    [Export("CellData"), Browsable(true)]
    public ICell CellData{ get; set; }

    /// <summary>
    /// Static control generator
    /// </summary>
    /// <returns>A control instance</returns>
    public static HorizontalGridLines Create()
    {
        var arr = NSBundle.MainBundle.LoadNib("HorizontalGridLines", null, null);
        var v = Runtime.GetNSObject<HorizontalGridLines>(arr.ValueAt(0));

        return v;
    }

    /// <summary>
    /// Drawing override
    /// </summary>
    /// <param name="rect">The content bounds</param>
    public override void Draw(CGRect rect)
    {
        base.Draw(rect);
        int numOfLines = this.CellData.ActivityRows.Count;

        var context = UIGraphics.GetCurrentContext();

        context.SetLineWidth(2);
        context.SetLineDash(0, new nfloat[] { 3, 4 });
        UIColor.Black.SetStroke();

        int y = 0;

        int width = (int)this.Frame.Width;
        int height = (int)this.Frame.Height;
        int heightPerLine = y = height / numOfLines;

        for (int i = 0; i < numOfLines - 1; i++)
        {
            var path = new CGPath();
            CGPoint[] lines = new CGPoint[2];
            lines[0] = new PointF(0, y);
            lines[1] = new PointF(width, y);
            y += heightPerLine;
            path.AddLines(lines);
            path.CloseSubpath();
            context.AddPath(path);
        }

        context.DrawPath(CGPathDrawingMode.FillStroke);
    }
}`

非常感谢任何帮助,谢谢! :)

1 个答案:

答案 0 :(得分:0)

所以我发现了这样做的方法:

  • 在您创建的自定义控件上,创建一个您要为其分配数据的公共属性。
  • 在XAML上将 {Binding。} 分配给您刚刚创建的公共属性,前提是它们属于同一类型。
  • 可以在 LayoutSubviews()方法期间/之后从自定义控件中访问数据。

例如:

<iOSControls:CellContent CellData="{Binding .}"/>

BindingContext属性似乎是标准Xamarin控件的一部分,而不是自定义本机控件。