Creating Reusable XAML User Controls with Xamarin Forms
In the previous post on making fancy layouts with Xamarin Forms we saw how you can design a Dashboard style application that stretches to fill any device size. However one of the challenges of the particular design we chose for Falafel 2 Go was the need to support the concept of an Image Button, where both the icon and the text work as a single control to launch an activity.
Xamarin Forms does provide an ImageCell control, which can be used in a TableView to render both text and image as a single control. However, this control is laid out horizontally with the text positioned on the right side of the image as you would expect for a list of items.

While we could likely acheive a more precise layout with a custom renderer, we found a much more elegnat, and more importantly, reusable option by instead creating a User Control.
XAML User Controls
The concept of User Controls is not new, and exists in many different platforms including Silverlight, XAML for Windows and Windows Phone as well as Web Forms. Basically the idea is to create a small container for 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 behavior.
Because User Controls are so useful (and simple to create) on other platforms, we were pleased and relieved to discover that Xamarin Forms supports them as well. While we weren’t able to find any documentation on the matter, with some experimentation we discovered the solution below. If there are official docs for this, please let me know in the comments so I can link to them!
Creating the Xamarin Forms User Control
Begin by adding a regular Xamarin Forms XAML Control to the project. By default this creates a ContentPage. For our layout, we want the image and text to flow vertically, so it makes sense to use a StackLayout, which is why we named the control StackLayoutButton. We can then change the XAML so that the control is also a StackLayout, as shown in the complete example later in the post.
In addition, the code-behind class by default doesn’t inherit from any base class. Usually you would modify this to be a ContentPage to both match the XAML definition as well as expose the properties and methods of the base control. However, because we’re using a StackLayout, we simply needed to update this to inherit from that control. This is also shown later in the full code-behind snippet.
By changing the class of the control we can proceed to add additional XAML controls to the StackLayout to make up the overall User Control. In this case we’re adding both the Image and Label controls as shown in the complete code below, completing the self-contained StackLayoutButton. Notice that we can define the properties for each control so that they are global to all instances of the button, eliminating the need to set them over and over for each one.
But what if we want to vary the properties on a specific control?
Accessing Child Controls and Properties
Because the individual controls are defined inside the StackLayout, we don’t have direct access to them from the User Control when we add them to the main page. However, we can workaround this by adding get and set properties to the StackLayoutButton which expose either the individual properties of a control, or the entire control itself.
If you review the full code of the StackLayoutButton code-behind below, you see that we’ve created two additional public properties. The TextColor sets or returns the value of the Label property so it can be set at the UserControl level. The other Label control returns the actual Label itself, so that we could potentially access and modify any property of that control.
This is demonstrated in the code-behind for the ActivitesPage control, where we access an instance of the StackLayoutButton by name, and can then access theTextControl property to set the BackgroundColor of that control.
Here’s what the final example page looks like. We’ve combined the two options to change both the Font color and the BackgroundColor using the exposed properties for specific buttons.

At last, here are the complete code samples for the controls, starting with the XAML for the StackLayoutButton:
<StackLayout xmlns=“http://xamarin.com/schemas/2014/forms”
xmlns:common=“clr-namespace:Falafel2GoV2.Common;assembly=Falafel2GoV2”
xmlns:x=“http://schemas.microsoft.com/winfx/2009/xaml”
x:Class=“Falafel2GoV2.Controls.StackLayoutButton“>
<Image x:Name=“Icon” Source=“{Binding Icon}” />
<Label x:Name=“Text” Text=“{Binding Title}” HorizontalOptions=“Center” LineBreakMode=“NoWrap” Font=“Small” TextColor=“{x:Static common:ColorResources.ListTitle}” />
</StackLayout>
The StackLayoutButton code-behind:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;namespace Falafel2GoV2.Controls
{
public partial class StackLayoutButton : StackLayout
{
public Color TextColor
{
get { return this.Text.TextColor; }
set { this.Text.TextColor = value; }
}public Label TextControl
{
get { return this.Text; }
set { this.Text = value; }
}public StackLayoutButton()
{
InitializeComponent();
}
}
}
The ActivitiesView XAML:
<ContentPage xmlns=“http://xamarin.com/schemas/2014/forms”
xmlns:x=“http://schemas.microsoft.com/winfx/2009/xaml”
xmlns:common=“clr-namespace:Falafel2GoV2.Common;assembly=Falafel2GoV2”
xmlns:controls=“clr-namespace:Falafel2GoV2.Controls;assembly=Falafel2GoV2”
x:Class=“Falafel2GoV2.Views.ActivitiesPage”
Title=“{Binding ViewName}”
BackgroundImage=“mainBack.png“>
<ContentPage.Content>
<StackLayout Orientation=“Vertical” Padding=“{x:Static common:PaddingResources.MainBody}“>
<Label Text=“{Binding ViewName}” Font=“42” IsVisible=“{Binding IsWindowsPhone}” />
<ActivityIndicator IsRunning=“{Binding IsLoading}” IsVisible=“{Binding IsLoading}” Color=“{x:Static common:ColorResources.ActivityIndicator}” /><Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=“*” />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=“3*” />
<RowDefinition Height=“4*” />
</Grid.RowDefinitions><Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=“*” />
<ColumnDefinition Width=“*” />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=“*” />
</Grid.RowDefinitions><controls:StackLayoutButton BindingContext=“{Binding Blog}” TextColor=“Blue” /><controls:StackLayoutButton x:Name=“RedButton”Grid.Column=“1” BindingContext=“{Binding Training}” TextColor=“Red” />
</Grid><
Grid Grid.Row=“1“>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=“*” />
<ColumnDefinition Width=“*” />
<ColumnDefinition Width=“*” />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=“*” />
<RowDefinition Height=“*” />
</Grid.RowDefinitions><
controls:StackLayoutButton BindingContext=“{Binding Facebook}” />
<controls:StackLayoutButton Grid.Column=“1” BindingContext=“{Binding Twitter}” />
<controls:StackLayoutButton Grid.Column=“2” BindingContext=“{Binding Google}” /><
controls:StackLayoutButton Grid.Row=“1” BindingContext=“{Binding Eventboard}” />
<controls:StackLayoutButton Grid.Row=“1” Grid.Column=“1” BindingContext=“{Binding Website}” />
<controls:StackLayoutButton Grid.Row=“1” Grid.Column=“2” BindingContext=“{Binding Contact}” />
</Grid>
</Grid>
</StackLayout>
</ContentPage.Content>
</ContentPage>
And finally the ActivitiesView code-behind:
using System.Collections.Generic;
using Falafel2GoV2;
using Falafel2GoV2.Views;
using Xamarin.Forms;
using Falafel2GoV2.ViewModels;
using Falafel2GoV2.Controls;
using Falafel2GoV2.Models;namespace Falafel2GoV2.Views
{
public partial class ActivitiesPage : ContentPage
{private ActivitiesViewModel vm;public ActivitiesPage()
{
InitializeComponent();
vm = new ActivitiesViewModel();
this.BindingContext = vm;RedButton.TextControl.BackgroundColor =Color.Black;
}}
}
Wrapping Up and Next Steps
By creating a User Control we were able to eliminate the need to define several copies of controls, encapsulating the controls into a single container so it can be defined with a single line a code. In addition, because we added properties to the control, we allow each instance of the control to have its own properties, and even behaviors.
The only thing left is to allow the user to Tap this new custom button to launch the activity. We’ll see how easy this is to do in the next post.
Until then, as always, I hope this was helpful!
from:http://blog.falafel.com/creating-reusable-xaml-user-controls-xamarin-forms/
Creating Reusable XAML User Controls with Xamarin Forms的更多相关文章
- Xamarin.Forms移动开发系列4 :XAML基础
摘要 本文介绍Xamarin.Forms创建用户界面的语言:XAML基础部分. 前言 本文介绍Xamarin.Forms定义用户界面的语言:XAML. 本篇篇幅较长,主要讲述XAML语法,以及对其他基 ...
- Xamarin.Forms之XAML
官网参考 XAML基础知识 XAML(eXtensible Application Markup Language)可扩展应用程序标记语言,允许开发者在Xamarin.Forms应用中采用标记而不是代 ...
- Xamarin.Forms 开发资源集合(复制)
复制:https://www.cnblogs.com/mschen/p/10199997.html 收集整理了下 Xamarin.Forms 的学习参考资料,分享给大家,稍后会不断补充: UI样式 S ...
- Xamarin.Forms 开发资源集合
收集整理了下 Xamarin.Forms 的学习参考资料,分享给大家,稍后会不断补充: UI样式 Snppts: Xamarin Forms UI Snippets. Prebuilt Templat ...
- Xamarin.Forms介绍
On May 28, 2014, Xamarin introduced Xamarin.Forms, which allows you to write user-interface code tha ...
- Xamarin.Forms 简介
An Introduction to Xamarin.Forms 来源:http://developer.xamarin.com/guides/cross-platform/xamarin-forms ...
- Add AI feature to Xamarin.Forms app
Now, AI is one of important technologies.Almost all platforms have API sets of AI. Following list is ...
- 在 Xamarin.Forms 实现密码输入EntryCell
在 Xamarin.Forms 中,我们通常使用 TableView 来构建输入表单.Xamarin 为我们提供了 EntryCell 用于输入文本,但是其并不支持密码输入,即密码掩码.这里要对 En ...
- Xamarin.Forms 自定义控件(呈现器和效果)
Xamarin.Forms 使用目标平台的本机控件呈现用户界面,从而让 Xamarin.Forms 应用程序为每个平台保留了相应的界面外观.凭借效果,无需进行自定义呈现器实现,即可自定义每个平台上的本 ...
随机推荐
- BAT脚本加防火墙455端口
@echo off mode con: cols=85 lines=30 :NSFOCUSXA title WannaCry勒索病毒安全加固工具 color 0A cls echo. echo. ec ...
- poj1142
分解质因数 #include <iostream> #include <cmath> using namespace std; int sum(int n) { ; ) { a ...
- Android安全系列之:如何在native层保存关键信息
相信大家在日常开发中都要安全层面的需求,最典型的莫过于加密.而apk是脆弱的,反编译拿到你的源码轻而易举,这时候我们就需要更保险的手段来保存密钥之类的关键信息.本文就细致地讲解简单却实用的native ...
- Java中 equals 和 == 的比较
先来看这样一个题目,假设有以下代码 下列选项中返回false的语句是? String s = "hello"; String t = "hello"; char ...
- Linux 下crontab 详解转
http://yaksayoo.blog.51cto.com/510938/162062 Linux计划任务工具cron用法详解 linux下大名鼎鼎的计划任务工具crontab的使用介绍baidu. ...
- chrome书签(收藏栏)的导入导出
- Windows 下 MySql 5.7.20安装及data和my.ini文件的配置(转)
Windows 下 MySql 5.7.20安装及data和my.ini文件的配置 本文通过图文并茂的形式给大家介绍了MySql 5.7.20安装及data和my.ini文件的配置方法. my ...
- Java反射初探 ——“当类也学会照镜子”
反射的作用 开门见山地说说反射的作用 1.为我们提供了全面的分析类信息的能力 2.动态加载类 我理解的“反射”的意义 (仅个人理解哈) 我理解的java反射机制就是: 提供一套完善而强大的 ...
- 大数据技术之_16_Scala学习_01_Scala 语言概述
第一章 Scala 语言概述1.1 why is Scala 语言?1.2 Scala 语言诞生小故事1.3 Scala 和 Java 以及 jvm 的关系分析图1.4 Scala 语言的特点1.5 ...
- 跟厂长学PHP7内核(六):变量之zval
记得网上流传甚广的段子"PHP是世界上最好的语言",暂且不去讨论是否言过其实,但至少PHP确实有独特优势的,比如它的弱类型,即只需要$符号即可声明变量,使得PHP入手门槛极低,成为 ...