ContentPage Customization using Xamarin.Forms


Isn't it fun,

to instantly listen to a blog on the go? PLAY !

 
 

ContentPage Customization using Xamarin.Forms

Table of Content

Introduction

ContentPage is the simplest and most common page among all the types of pages available in XamarinForms. It is mostly used to display only a single view that can be StackLayout or GridLayout or ScrollLayout. It is a visual element of the page and occupies most of the screen.

There is a relationship between the ContentPage and its corresponding native controls that implement the Content Page and that is seen in the following image.

RunAnalyzer

Image Source

In every Xamarin.Forms, each control has some following renderer with it for every platform and it creates an instance of its native control.

When a ContentPage is rendered in a Xamarin.Forms Application then, in an iOS device, when the PageRenderer class is instantiated, it instantiates a native UIViewerController control. In an Android device, the PageRenderer class instantiates a GroupView control and in a UWP the PageRenderer class instantiates a FrameworkElement control.

We can take advantage of the rendering process to implement a customization of platform-specific ContentPage by creating a custom renderer of it on every platform.

  1. We firstly create a ContentPage in Xamarin.Forms.
  2. Then, consume the page from Xamarin.Forms.
  3. Creating Custom Renderer for the ContentPage in Xamarin.Forms on each Platform.

Creating a ContentPage in Xamarin.Forms:

We can add a ContentPage that is not altered in Xamarin.Forms shared folder by right-clicking on VCL folder and then click on Add button and select New Item and then from Xamarin.Forms we can add ContentPage.xaml and name it as CameraPage.

The ContentPage will have the code as:

CameraPage.xaml







Likewise, the cs file should not be tempered.

CameraPage.xaml.cs

using System;
using Xamarin.Forms;

namespace CustomRenderer
{
	public partial class CameraPage : ContentPage
	{
		public CameraPage()
		{
			InitializeComponent();
		}
	}
}

The live camera feed on each platform can be displayed by creating an instance of CameraPage.

No additional changes are needed in the class as all the customization will be performed in the custom renderer class.

   

Consuming the ContentPage from Xamarin.Forms

In Xamarin.Forms, the CameraPage must be displayed and for that, a button must be placed in MainPage.

When the button in the MainPage is pressed it generates an instance that implements the “OnTakePhotoButtonClicked” function.

MainPage.xaml



    
        

MainPage.xaml.cs

using System;
using Xamarin.Forms;
namespace CustomRenderer
{
	public partial class MainPage : ContentPage
	{
		public MainPage()
		{
			InitializeComponent();
		}
		async void OnTakePhotoButtonClicked(object sender, EventArgs e)
		{
			await Navigation.PushAsync(new CameraPage());
		}
	}
}

Using this code, we can easily navigate to CameraPage on which the custom renderer starts customizing the appearance of the page on each platform.

CustomRenderer.csproj



	
		netstandard2.0
	

	
		full
	

	
		
	


		
			MSBuild:UpdateDesignTimeXaml
		
		
			MSBuild:UpdateDesignTimeXaml
		
	



Creating a Custom Renderer for every platform

For creating a custom renderer for ContentPage we have to follow these steps:

  1. In the first step, a subclass of PageRenderer is created.
  2. Then in the second step, overriding of class method OnElementChanged is performed that renders all native controls of the page and the customization code is written there.

    The method is invoked when the related Xamarin.Forms are created.

  3. An ExportRenderer attribute must be added to the Page Renderer class to specify that it will always be used to render the Xamarin.Forms pages.

RunAnalyzer

Image Source

The above image shows the relationship between each of the projects and all their responsibilities with the application.

The CameraPageRenderer classes are derived from the PageRenderer class of a particular platform and it renders the CameraPage for platform-specific applications.

The CameraPageRenderer class which has an overridden method OnElementChanged is the area where we can do coding for the customization of the native page.

This method has two properties i.e. NewElement and OldElement of the parameter named ElementChangedEventArgs.

These properties are used to know that to which element of Xamarin.Forms element it is attached and to which Xamarin.Forms element it was attached to, respectively.

Using Element property, we can render the Xamarin.Forms page instance.

Every custom renderer class is designed using the ExportRenderer attribute using which we can render with Xamarin.Forms.

This attribute has two parameters, first is the type name of Xamarin.Forms page that is being rendered and the second is the type name of the custom renderer.

“Assembly” is the prefix to the ExportRenderer attribute that describes that the attribute is being applied to the whole assembly.

For Android:

CameraPageRenderer.cs

[assembly: ExportRenderer(typeof(CameraPage), typeof(CameraPageRenderer))]
namespace CustomRenderer.Droid
{
    public class CameraPageRenderer : PageRenderer, TextureView.ISurfaceTextureListener
    {
        ...
        public CameraPageRenderer(Context context) : base(context)
        {
        }
        protected override void OnElementChanged(ElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null || Element == null)
            {
                return;
            }
            try
            {
                SetupUserInterface();
                SetupEventHandlers();
                AddView(view);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(@"            ERROR: ", ex.Message);
            }
        }
        ...
    }
}

MainActivity.cs

using Android.App;
using Android.Content.PM;
using Android.OS;

namespace CustomRenderer.Droid
{
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            Instance = this;
            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }
    }
}

An Android ViewGroup control is instantiated by the invocation of the base class’s OnElementChanged method.

The live stream camera is only rendered and it is specified that the renderer is not attached to Xamarin.Forms existing elements and also specified that a page instance is existing and this is being rendered by the custom renderer.

 

Planning to Hire Xamarin App Development Company ?

Your Search ends here.

 

For UWP

CameraPageRenderer.cs

[assembly: ExportRenderer(typeof(CameraPage), typeof(CameraPageRenderer))]
namespace CustomRenderer.UWP
{
    public class CameraPageRenderer : PageRenderer
    {
        ...
        protected override void OnElementChanged(ElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null || Element == null)
            {
                return;
            }

            try
            {
                ...
                SetupUserInterface();
                SetupBasedOnStateAsync();

                this.Children.Add(page);
            }
            ...
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            page.Arrange(new Windows.Foundation.Rect(0, 0, finalSize.Width, finalSize.Height));
            return finalSize;
        }
        ...
    }
}
MainPage.xaml.cs:
namespace CustomRenderer.UWP
{
    public sealed partial class MainPage
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.LoadApplication(new CustomRenderer.App());
        }
    }
}

A UWP FramewrokElement control is instantiated by the invocation of the base class’s OnElementChanged method.

The live stream camera is only rendered and it is specified that the renderer is not attached to Xamarin.Forms existing elements and also specified that a page instance is existing and this is being rendered by the custom renderer.

At the time of implementing PageRenderer on UWP, we must implement an ArrangeOverride method that arranges the controls on the page as the base renderer is not aware of what to do with it, otherwise, a blank page will be displayed.

Conclusion

In this article, we learned how to develop a custom renderer of ContentPage and from this, we understand how to render a page in a content page and what needs to override at which stage of implementation.

Through this, we can enable the developers to override the native rendering with the required platform-specific customization.

ContentPage Customization using Xamarin.Forms

Table of Content

Introduction

ContentPage is the simplest and most common page among all the types of pages available in XamarinForms. It is mostly used to display only a single view that can be StackLayout or GridLayout or ScrollLayout. It is a visual element of the page and occupies most of the screen.

There is a relationship between the ContentPage and its corresponding native controls that implement the Content Page and that is seen in the following image.

RunAnalyzer

Image Source

In every Xamarin.Forms, each control has some following renderer with it for every platform and it creates an instance of its native control.

When a ContentPage is rendered in a Xamarin.Forms Application then, in an iOS device, when the PageRenderer class is instantiated, it instantiates a native UIViewerController control. In an Android device, the PageRenderer class instantiates a GroupView control and in a UWP the PageRenderer class instantiates a FrameworkElement control.

We can take advantage of the rendering process to implement a customization of platform-specific ContentPage by creating a custom renderer of it on every platform.

  1. We firstly create a ContentPage in Xamarin.Forms.
  2. Then, consume the page from Xamarin.Forms.
  3. Creating Custom Renderer for the ContentPage in Xamarin.Forms on each Platform.

Creating a ContentPage in Xamarin.Forms:

We can add a ContentPage that is not altered in Xamarin.Forms shared folder by right-clicking on VCL folder and then click on Add button and select New Item and then from Xamarin.Forms we can add ContentPage.xaml and name it as CameraPage.

The ContentPage will have the code as:

CameraPage.xaml







Likewise, the cs file should not be tempered.

CameraPage.xaml.cs

using System;
using Xamarin.Forms;

namespace CustomRenderer
{
	public partial class CameraPage : ContentPage
	{
		public CameraPage()
		{
			InitializeComponent();
		}
	}
}

The live camera feed on each platform can be displayed by creating an instance of CameraPage.

No additional changes are needed in the class as all the customization will be performed in the custom renderer class.

   

Consuming the ContentPage from Xamarin.Forms

In Xamarin.Forms, the CameraPage must be displayed and for that, a button must be placed in MainPage.

When the button in the MainPage is pressed it generates an instance that implements the “OnTakePhotoButtonClicked” function.

MainPage.xaml



    
        

MainPage.xaml.cs

using System;
using Xamarin.Forms;
namespace CustomRenderer
{
	public partial class MainPage : ContentPage
	{
		public MainPage()
		{
			InitializeComponent();
		}
		async void OnTakePhotoButtonClicked(object sender, EventArgs e)
		{
			await Navigation.PushAsync(new CameraPage());
		}
	}
}

Using this code, we can easily navigate to CameraPage on which the custom renderer starts customizing the appearance of the page on each platform.

CustomRenderer.csproj



	
		netstandard2.0
	

	
		full
	

	
		
	


		
			MSBuild:UpdateDesignTimeXaml
		
		
			MSBuild:UpdateDesignTimeXaml
		
	



Creating a Custom Renderer for every platform

For creating a custom renderer for ContentPage we have to follow these steps:

  1. In the first step, a subclass of PageRenderer is created.
  2. Then in the second step, overriding of class method OnElementChanged is performed that renders all native controls of the page and the customization code is written there.

    The method is invoked when the related Xamarin.Forms are created.

  3. An ExportRenderer attribute must be added to the Page Renderer class to specify that it will always be used to render the Xamarin.Forms pages.

RunAnalyzer

Image Source

The above image shows the relationship between each of the projects and all their responsibilities with the application.

The CameraPageRenderer classes are derived from the PageRenderer class of a particular platform and it renders the CameraPage for platform-specific applications.

The CameraPageRenderer class which has an overridden method OnElementChanged is the area where we can do coding for the customization of the native page.

This method has two properties i.e. NewElement and OldElement of the parameter named ElementChangedEventArgs.

These properties are used to know that to which element of Xamarin.Forms element it is attached and to which Xamarin.Forms element it was attached to, respectively.

Using Element property, we can render the Xamarin.Forms page instance.

Every custom renderer class is designed using the ExportRenderer attribute using which we can render with Xamarin.Forms.

This attribute has two parameters, first is the type name of Xamarin.Forms page that is being rendered and the second is the type name of the custom renderer.

“Assembly” is the prefix to the ExportRenderer attribute that describes that the attribute is being applied to the whole assembly.

For Android:

CameraPageRenderer.cs

[assembly: ExportRenderer(typeof(CameraPage), typeof(CameraPageRenderer))]
namespace CustomRenderer.Droid
{
    public class CameraPageRenderer : PageRenderer, TextureView.ISurfaceTextureListener
    {
        ...
        public CameraPageRenderer(Context context) : base(context)
        {
        }
        protected override void OnElementChanged(ElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null || Element == null)
            {
                return;
            }
            try
            {
                SetupUserInterface();
                SetupEventHandlers();
                AddView(view);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(@"            ERROR: ", ex.Message);
            }
        }
        ...
    }
}

MainActivity.cs

using Android.App;
using Android.Content.PM;
using Android.OS;

namespace CustomRenderer.Droid
{
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            Instance = this;
            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }
    }
}

An Android ViewGroup control is instantiated by the invocation of the base class’s OnElementChanged method.

The live stream camera is only rendered and it is specified that the renderer is not attached to Xamarin.Forms existing elements and also specified that a page instance is existing and this is being rendered by the custom renderer.

 

Planning to Hire Xamarin App Development Company ?

Your Search ends here.

 

For UWP

CameraPageRenderer.cs

[assembly: ExportRenderer(typeof(CameraPage), typeof(CameraPageRenderer))]
namespace CustomRenderer.UWP
{
    public class CameraPageRenderer : PageRenderer
    {
        ...
        protected override void OnElementChanged(ElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null || Element == null)
            {
                return;
            }

            try
            {
                ...
                SetupUserInterface();
                SetupBasedOnStateAsync();

                this.Children.Add(page);
            }
            ...
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            page.Arrange(new Windows.Foundation.Rect(0, 0, finalSize.Width, finalSize.Height));
            return finalSize;
        }
        ...
    }
}
MainPage.xaml.cs:
namespace CustomRenderer.UWP
{
    public sealed partial class MainPage
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.LoadApplication(new CustomRenderer.App());
        }
    }
}

A UWP FramewrokElement control is instantiated by the invocation of the base class’s OnElementChanged method.

The live stream camera is only rendered and it is specified that the renderer is not attached to Xamarin.Forms existing elements and also specified that a page instance is existing and this is being rendered by the custom renderer.

At the time of implementing PageRenderer on UWP, we must implement an ArrangeOverride method that arranges the controls on the page as the base renderer is not aware of what to do with it, otherwise, a blank page will be displayed.

Conclusion

In this article, we learned how to develop a custom renderer of ContentPage and from this, we understand how to render a page in a content page and what needs to override at which stage of implementation.

Through this, we can enable the developers to override the native rendering with the required platform-specific customization.