Xamarin Forms User Control

Xamarin Forms doesn’t have a control called a User Control, similar to what you might be familar with in WPF. However we can make any VisualElement, or combination of VisualElement’s into a reusable control, to use on different pages, just like a User Control.

Create Control

Create a new ContentView.

Going into the XAML, while you can keep the ContentView as your root element, I prefer to remove it and have a different layout control at the root, e.g. a Grid.

<?xml version="1.0" encoding="UTF-8"?>
<Grid xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="Mobile.UserControl">

      <Label Text="Hello, I'm a UserControl" />
 
</Grid>

In your code behind, make sure you change the inheritance from a ContentView to a Grid.

public namespace Mobile
{
    public partial class UserControl : Grid
    {
        public UserControl()
        {
            InitializeComponent();
        }
    }
}

Using The Control

Using the control is easy, you first need to create an xmlns prefix, referencing the namespace the control is in. Then using that to place the control, where ever you want on your page.

<?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:control="clr-namespace:Mobile"

             x:Class="Mobile.MainPage"
             Title="Main Page">

     <control:UserControl />

</ContentPage>

Bindable Properties

Next, you might want to make your control, have a bindable property to pass data through to it, on each page it is used. First, create a Bindable Property in your UserControl. It doesn’t have to be bindable if you just want to pass a static value through, however if you want to bind to it, you must make it bindable.

public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(UserControl));

public string Text
{
    get
    {
        return (string)GetValue(TextProperty);
    }
    set
    {
        SetValue(TextProperty, value);
}

Now, in the XAML of your user control, you will want to change the label text to bind from this property. Notice, that you also set the name of the page and mark the source of the binding to the page. If you remember about BindingContexts, the user control will take the binding context of the page it is placed on. Hence you need to tell it to look in the UserControl, not the page it is placed on for the value of the property.

<Grid xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="Mobile.UserControl"
      x:Name="this">
    <Label Text="{Binding Text, Source={x:Reference this}}" />
</Grid>

Going to your MainPage, you can now assign a value to the Text property. You can also use {Binding PropertyName} if you want, as this is a bindable property.

<control:UserControl Text="Hello from MainPage!" />
Microsoft MVP | Xamarin MVP | Xamarin Certified Developer |
Exrin MVVM Framework | Xamarin Forms Developer | Melbourne, Australia

Related Posts

6 Comments

  1. abdullah tahan

    you can easily bind your contentview to you viewmodel by assigning BindingContext=”{Binding}” so in your contentview you don’t really need to create new bindable properties .

    1. Adam Pedley

      The problem with that approach, is that your UserControl may have conflicting property names with whatever page you place this control on. If you want to make a truly reusable control, its best to have your own BindableProperties. There may be a few other issues that come along as well.

      But if you want it quick and easy, then yes, you can switch the BindingContext of the UserControl to your ViewModel, to just have them passed straight through.

  2. Dan Meier

    Once I’ve made my UserControl, how can I use it in other projects? Indeed, can I create a project containing only UserControls and package it up to for use in different projects?

    1. Adam Pedley

      Yes, you just create a new DLL, and place them all in there. When you reference them from your other projects, you just need to add the assembly name as well.

      xmlns:control=”clr-namespace:Mobile;assembly=MyAssemblyName”

      1. Dan Meier

        Many thanks, Adam. I’m creating the user control as a PCL project without any kind of cross-platform tie-in, compiled as a DLL, and included as a reference in a Xamarin Forms project. Works great! Just one issue, though. The user control contains an image file. I’m placing this in an Assets directory within the user control project and referencing it as… Image.Source=“Assets/ImageFile.png” However, the image doesn’t show up in the Xamarin Forms project. The user control appears, but the location where the image should appear is just blank.

        If I put the image file in the Assets directory in the Xamarin Forms UWP project and run the UWP project, the image shows up as expected within the user control. But if I can’t completely encapsulate the user control and all its resources in the referenced DLL, that seems to defeat part of the purpose of creating the DLL.

        What am I missing? I must be doing something wrong!

        1. Adam Pedley

          Images can be tricky in a DLL. UWP looks for images starting at the root, hence Assets/name.png will work, however Android starts looking for images starting at Resources/Drawable, hence you would have to put the image in Resources/Drawable/Assets/name.png

          If you want to include an image in your DLL, this can be done, I forget how off the top of my head. I think you need to look at Embedded Resource and reference that instead.

Leave A Comment?