Learn Xamarin.Forms Control Template by making a Button with built-in Loading Indicator in 4 steps
In Xamarin.Forms, Control Template offers a powerful way to build a template. The template is built by composing smaller parts. But building a template is not the end goal. The end goal is to use a so-built template to make UI controls and use them anywhere without having to duplicate common codes.
I’m going to show how to implement a button for a Xamarin.Forms app that has the following special features: (a) Upon being tapped-on, the button will show a loading indicator (Activity Indicator) indicating the app is doing some work asynchronously. (b) This button can be re-used every where in the application without any code duplication.
As an example, the button, in normal state looks like:
Upon being tapped-on, the button will show a loading indicator and looks like:
Side note: I came up with the prefix AsyncButton to be used in the naming which might or might not be the best choice. But for the rest of this post, we’re stuck with it.
Step 0. Read the official docs (optional)
Read about Xamarin.Forms Control Templates and Relative Binding. If it’s a little vague, hopefully, the docs are more valuable after the following 4 steps.
Step 1. Create Bindable Properties in a View file
Create a new file named AsyncButtonView.cs
(just a plain old .cs
file, no accompanying .xaml
file):
Point of interest: This class AsyncButtonView
subclasses from ContentView
and is really simple. It just lists all the bindable properties. Glancing at the variables names such ButtonCornerRadius
, ButtonBackgroundColor
, ButtonTextColor
, ButtonText
, etc, we can quickly tell that these properties are used later on to customize the look and feel of a button. But this class does not “blueprint” how to construct the button. That’s for step 2.
Step 2. Build a Control Template for the Button
A Control Template “blueprints” how to build the UI for the control. Create a new file named AsyncButtonControlTemplateResourceDictionary.xaml
and put it in the same folder with App.xml
(Every Xamarin.Forms app should already have an App.xml
file):
Point of interest: The Control Template above instructs to build the button by composing smaller parts. It instructs to layout a Xamarin.Forms Button next to a Xamarin.Forms ActivityIndicator horizontally (line 9 through 15). Then it instructs to put this layout inside a Xamarin.Forms Frame (line 5 through 16). This Frame
class allows for the Button’s rounded corners. Finally, we have a Button ControlTemplate
out this construction by wrapping it inside a Xamarin.Forms ControlTemplate (line 4 through 17).
But if you look more closely at this file, this Button ControlTemplate
is not connected to AsyncButtonView
in step 1 in any way. The connection will be made when this Button ControlTemplate
is actually used to make a button. All the bindings however are already specified by now as illustrated by the following line.
BackgroundColor="{Binding Source={RelativeSource TemplatedParent},Path=ButtonBackgroundColor}"
Step 3: Consume the Button ControlTemplate to make a button
Finally we are ready to use the Button ControlTemplate
to make an Async Button. As an example, the following file shows how to put together everything that we have created so far:
Point of interest: The file in step 2 AsyncButtonControlTemplateResourceDictionary.xaml
is referenced in the ResourceDictionary
on line 14. On line 20, the AsyncButtonView
and the Button ControlTemplate
work together along with the supplied values for the rest of the properties. These 2 lines (line 14 and line 20) “connects” the bindable properties in step 1 with the UI Control Template in step 2. Line 9 references the ViewModel
which we will do in step 4.
Step 4: Add a ViewModel
Cross posted on dev.to