Sunday, March 22, 2015

NControl - Cross Platform Custom Controls for Xamarin.Forms

NControl is a Xamarin.Forms wrapper control built around the NGraphics library enabling developers to create custom controls without the need for custom renderers.

The project is hosted on Github and is distributed under the MIT license.

The library contains the NControlView class where real custom cross-platform drawing can be performed without the need for native implementations thanks to the NGraphics library. NControlView can be used both to do custom drawing and to create complex custom controls.

Supported Platforms:
The library currently supports native renderers for the following platforms:
  • Android
  • iOS Unified
A Windows Phone edition of the control is planned for a later release.

Installation:
Install in your iOS, Android and Forms project using this package from Nuget.

Remember to to add calls to NControlViewRenderer.Init()after Forms.Init() in your AppDelegate and in your MainActivity.

Example Usage:
In your Xamarin.Forms project, add a new NControlView element to your page in the constructor and provide a drawing function where your custom drawing is performed:

  Content = new NControlView {
      DrawingFunction = (canvas, rect) => {
          canvas.DrawLine(rect.Left, rect.Top, rect.Width, rect.Height, NGraphics.Colors.Red);
          canvas.DrawLine(rect.Width, rect.Top, rect.Left, rect.Height, NGraphics.Colors.Yellow);
      }
  };

Subclassing:
You can also create a subclass of the NControlView class and override its Draw function to add your own custom drawing:

public class MyControl: NControlView
{
  public override void Draw(NGraphics.ICanvas canvas, NGraphics.Rect rect)
  {
    canvas.DrawLine(rect.Left, rect.Top, rect.Width, rect.Height, NGraphics.Colors.Red);
    canvas.DrawLine(rect.Width, rect.Top, rect.Left, rect.Height, NGraphics.Colors.Yellow);
  }
}

Complex Controls:
NControlView supports containing other controls since it inherits from the ContentView class. Building composite controls is as simple as setting the Content property of your subclassed control:

public class MyControl: NControlView
{
  public MyControl()
  {
    Content = new Label {BackgroundColor = Xamarin.Forms.Color.Transparent};
  }

  public override void Draw(NGraphics.ICanvas canvas, NGraphics.Rect rect)
  {
    canvas.DrawLine(rect.Left, rect.Top, rect.Width, rect.Height, NGraphics.Colors.Red);
    canvas.DrawLine(rect.Width, rect.Top, rect.Left, rect.Height, NGraphics.Colors.Yellow);
  }
}

Now your custom control will have a label that can draw text in the control. Remember that you can set the Content property to point to anything as long as it is a VisualElement. This means that you can add layouts containing other controls as well as a single control.

Invalidation:
If you need to invalide the control when a property has changed, call the Invalidate() function to redraw your control:

public class MyControl: NControlView
{
  public MyControl()
  {
    Content = new Label {BackgroundColor = Xamarin.Forms.Color.Transparent};
  }

  public string Text { 
    get 
    { 
      return (Content as Label).Text; 
    }
    set 
    { 
      (Content as Label).Text = value;
      Invalidate();
    }
  }

  public override void Draw(NGraphics.ICanvas canvas, NGraphics.Rect rect)
  {
    canvas.DrawLine(rect.Left, rect.Top, rect.Width, rect.Height, NGraphics.Colors.Red);
    canvas.DrawLine(rect.Width, rect.Top, rect.Left, rect.Height, NGraphics.Colors.Yellow);
  }
}

Touch events
The NControlView class also handles touch events - look at the CircularButtonControl for an example of how this can be used.

Demo controls
The demo solution contains a few different controls based on the NControlView class:


  • RoundedCornerControl
  • CircularButtonControl
  • ProgressControl

The ProgressControl and the CircularButtonControl both internally uses the FontAwsomeLabel to display glyphs from the Font Awesome Icon font.

Notes
Note that the ProgressControl and the CircularButtonControl contains animations to make the user experience more alive. The demo solution also uses animation to add some eye candy to the demo itself.