Creating User Controls in Xamarin Forms

In my earlier blog about accordion user control, I just missed to explain about the whole need and purpose of user controls 🙂 . The concept of User Controls is not new, and exists in many different platforms including ASP.Net, XAML for Windows and Windows Phone as well as Web Forms. Basically the idea is to create a collection of controls that will be reused as a single control throughout the application.The User Control exposes properties allowing you to reuse the control while allowing each instance of the control to have different settings, layout, or behaviour.
Another benefit of user control is that we can bundle them separately in a project and can use them as a custom control in any other project/application and because of this very reason I personally prefer to create user controls for any repetitive UI I need in any of my applications.

As per Xamarin documentation, the view which should be mostly used to create user control should be ContentView. In earlier article I extended that to create an accordion and in this article I will be creating a very commonly required user control ‘Form Containers’ which looks something like following MockUp:
ContainerMockUp
Here we have a Container with Title with one background and content with different background, giving the screen a feel like Form control. Lets create similar UI in Xamarin Forms 🙂

So First create a new project in Xamarin/Visual Studio (see this article for steps) and add new ContentView XAML page. Add the following XAML to the control Page:

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FormContainer.MyContainer">
  <ContentView.Content>
    <Grid RowSpacing="0">
      <Grid.RowDefinitions>
        <RowDefinition Height="60" />
        <RowDefinition Height="*" />
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="5" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="5" />
      </Grid.ColumnDefinitions>
      <Frame Grid.Row="0" Grid.Column="1" x:Name="HeaderFrame" OutlineColor="Black" HasShadow="False">
        <Label x:Name="HeaderLabel" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
      </Frame>
      <Frame Grid.Row="1" Grid.Column="1" x:Name="ContentFrame" OutlineColor="Black" HasShadow="False">
      </Frame>
    </Grid>
  </ContentView.Content>
</ContentView>

In the above code we are creating a Grid with 2 Rows (one for header and second for content) and 3 columns (first and last is for giving the spacing). In the First Row we are putting the Frame with Header label and in Second row we are putting a blank frame for the content of the control.
As we can’t create properties of the control in XAML, so write following code in code behind of control to create it’s properties:

using Xamarin.Forms;
namespace FormContainer
{
    [ContentProperty("ContainerContent")]
    public partial class MyContainer : ContentView
    {

        public MyContainer()
        {
            InitializeComponent();
        }

        #region Properties

        public View ContainerContent
        {
            get { return ContentFrame.Content; }
            set { ContentFrame.Content = value; }
        }
        public Color ContentBackgroundColor
        {
            get { return ContentFrame.BackgroundColor; }
            set { ContentFrame.BackgroundColor = value;}
        }
        public string HeaderText
        { get { return HeaderLabel.Text; } set { HeaderLabel.Text = value; } }
        public Color HeaderTextColor
        { get { return HeaderLabel.TextColor; } set { HeaderLabel.TextColor = value; } }
        public Color HeaderBackGroundColor
        { get { return HeaderFrame.BackgroundColor; } set { HeaderFrame.BackgroundColor = value; } }
        #endregion
    }
}

As you can see from above code the control will have five properties, their names are self-explanatory for their requirements like one for ContainerContent, another for Content Background Color and so on.
This completes the code of the user control.
As an example on how to use the control in XAML lets create a new XAML ContentPage and add the following code in that to create two forms one for Login and one for SignUp:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:ctrl="clr-namespace:FormContainer;assembly=FormContainer"
             x:Class="FormContainer.XamlExample" Title="XAML Example" Padding="0,10,0,0">
  <ContentPage.Resources>
    <ResourceDictionary>
      <Style TargetType="Button">
        <Setter Property="BorderRadius" Value="10" />
        <Setter Property="BorderWidth" Value="2" />
        <Setter Property="WidthRequest" Value="100" />
        <Setter Property="HeightRequest" Value="30" />
        <Setter Property="HorizontalOptions"  Value="Center" />
        <Setter Property="VerticalOptions"    Value="Center" />
        <Setter Property="FontSize" Value="Medium" />
        <Setter Property="TextColor" Value="Red" />
      </Style>
    </ResourceDictionary>
  </ContentPage.Resources>
  <ContentPage.Content>
    <StackLayout Spacing="0" >
      <ctrl:MyContainer HeaderText="Login (XAML)" HeaderTextColor="White" HeaderBackGroundColor="Black" ContentBackgroundColor="#F0F0F0">
        <ctrl:MyContainer.ContainerContent>
          <StackLayout>
            <Entry Placeholder="User Name" />
            <Entry Placeholder="Password" />
            <Button Text="Login" />
          </StackLayout>
        </ctrl:MyContainer.ContainerContent>
      </ctrl:MyContainer>
      <BoxView  HeightRequest = "10"  />
      <ctrl:MyContainer HeaderText="Sign Up (XAML)" HeaderTextColor="White" HeaderBackGroundColor="Black" ContentBackgroundColor="#F0F0F0">
        <ctrl:MyContainer.ContainerContent>
          <StackLayout>
            <Entry Placeholder="First Name" />
            <Entry Placeholder="Last Name" />
            <Entry Placeholder="User Name" />
            <Entry Placeholder="Email" />
            <Entry Placeholder="Password" />
            <Entry Placeholder="Confirm Password" />
            <Button Text="Sign Up" />
          </StackLayout>
        </ctrl:MyContainer.ContainerContent>
      </ctrl:MyContainer>
    </StackLayout>
  </ContentPage.Content>
</ContentPage>

This is how the output will look on an iOS simulator:
FormContaineriOSExXaml
In the same way we can use this control for only showing data, lets create one Example for that but this time using C# code. So create a new Code only content Page and add following code to it :


using Xamarin.Forms;

namespace FormContainer
{
    public class CodeEaxmple : ContentPage
    {
        public CodeEaxmple()
        {
            Padding = new Thickness(0,10,0,10);
            Title = "Code Example";
            var vContentStack = new StackLayout
            {
                Children = {
                    new Label { Text = "Name : S Ravi Kumar", TextColor=Color.Red },
                     new Label { Text = "Place : India", TextColor=Color.Red },
                      new Label { Text = "Twitter : @srkrathore", TextColor=Color.Red },
                       new Label { Text = "Blog : http://err2solution.com/", TextColor=Color.Red },
                }
            };
            var vFormContainer = new MyContainer() {
                HeaderText = "My Details (Code)",
                HeaderTextColor = Color.Red,
                HeaderBackGroundColor= Color.Gray,
                ContentBackgroundColor = Color.White,
                ContainerContent = vContentStack
            };
            Content = vFormContainer;
        }
    }
}

This is how the output will look on an iOS simulator:
FormContaineriOSExCode
I have just scratched the surface of user control creation in Xamarin Forms, you can dig deeper into it buy executing the code for Android & Windows.The source code of sample application containing this user control and pages using the control can be downloaded from Github.
let me know if I have missed anything or you have any queries/suggestions.

🙂 Happy Coding 🙂

3 Comments

  1. Hello SRKRathore,
    If I make some UI of buttons and entrys in contentview(i.e. common code) ,How can I fetch buttons click events and entrys text on the page where I am reusing the code? Please help.

  2. Hi Prajakta,
    For both the things you will have to give the name of the control using x:Name property and then expose the control from code behind as a property.
    Regards
    S Ravi Kumar

Leave a Reply

Your email address will not be published.


*