Getting Started with Xamarin.Forms Guide
Getting Started with Xamarin.Forms Guide
Xamarin.Forms
Getting Started
Requirements
Hello, Xamarin.Forms
Part 1: Quickstart
Part 2: Deep Dive
Hello, Xamarin.Forms Multiscreen
Part 1: Quickstart
Part 2: Deep Dive
Introduction to Xamarin.Forms
XAML
XAML Basics
Part 1. Getting Started with XAML
Part 2. Essential XAML Syntax
Part 3. XAML Markup Extensions
Part 4. Data Binding Basics
Part 5. From Data Bindings to MVVM
XAML Compilation
Live Reload
XAML Previewer
XAML Namespaces
XAML Markup Extensions
Consuming XAML Markup Extensions
Creating XAML Markup Extensions
Field Modifiers
Passing Arguments
Bindable Properties
Attached Properties
Resource Dictionaries
XAML Standard (Preview)
Controls
Application Fundamentals
Accessibility
Setting Accessibility Values on User Interface Elements
App Class
App Lifecycle
Behaviors
Introduction
Attached Behaviors
Xamarin.Forms Behaviors
Reusable Behaviors
EffectBehavior
EventToCommandBehavior
Custom Renderers
Introduction
Renderer Base Classes and Native Controls
Customizing an Entry
Customizing a ContentPage
Customizing a Map
Customizing a Map Pin
Highlighting a Circular Area on a Map
Highlighting a Region on a Map
Highlighting a Route on a Map
Customizing a ListView
Customizing a ViewCell
Implementing a View
Implementing a HybridWebView
Implementing a Video Player
Creating the Platform Video Players
Playing a Web Video
Binding Video Sources to the Player
Loading Application Resource Videos
Accessing the Device's Video Library
Custom Video Transport Controls
Custom Video Positioning
Data Binding
Basic Bindings
Binding Mode
String Formatting
Binding Path
Binding Value Converters
The Command Interface
DependencyService
Introduction
Implementing Text-to-Speech
Checking Device Orientation
Checking Battery Status
Picking from the Photo Library
Effects
Introduction
Effect Creation
Passing Parameters
Parameters as CLR Properties
Parameters as Attached Properties
Invoking Events
Files
Gestures
Tap
Pinch
Pan
Localization
String and Image Localization
Right-to-Left Localization
Local Databases
MessagingCenter
Navigation
Hierarchical Navigation
TabbedPage
CarouselPage
MasterDetailPage
Modal Pages
Displaying Pop-Ups
Templates
Control Templates
Introduction
Control Template Creation
Template Bindings
Data Templates
Introduction
Data Template Creation
Data Template Selection
Triggers
User Interface
Animation
Simple Animations
Easing Functions
Custom Animations
BoxView
Button
Colors
Controls Reference
Pages
Layouts
Views
Cells
DataPages
Getting Started
Controls Reference
DatePicker
Graphics
Using CocosSharp in Xamarin.Forms
Using SkiaSharp in Xamarin.Forms
SkiaSharp Drawing Basics
Drawing a Simple Circle
Integrating with Xamarin.Forms
Pixels and Device-Independent Units
Basic Animation
Integrating Text and Graphics
Bitmap Basics
SkiaSharp Lines and Paths
Lines and Stroke Caps
Path Basics
The Path Fill Types
Polylines and Parametric Equations
Dots and Dashes
Finger Painting
SkiaSharp Transforms
The Translate Transform
The Scale Transform
The Rotate Transform
The Skew Transform
Matrix Transforms
Touch Manipulations
Non-Affine Transforms
3D Rotation
SkiaSharp Curves and Paths
Three Ways to Draw an Arc
Three Types of Bézier Curves
SVG Path Data
Clipping with Paths and Regions
Path Effects
Paths and Text
Path Information and Enumeration
SkiaSharp Bitmaps
Displaying Bitmaps
Creating and Drawing on Bitmaps
Cropping Bitmaps
Segmented Display of Bitmaps
Saving Bitmaps to Files
Accessing Bitmap Pixel Bits
Animating Bitmaps
Using UrhoSharp in Xamarin.Forms
Images
Layouts
StackLayout
AbsoluteLayout
RelativeLayout
Grid
FlexLayout
ScrollView
LayoutOptions
Margin and Padding
Device Orientation
Tablet & Desktop
Creating a Custom Layout
Layout Compression
ListView
Data Sources
Cell Appearance
List Appearance
Interactivity
Performance
Maps
Picker
Setting a Picker's ItemsSource Property
Adding Data to a Picker's Items Collection
Slider
Styles
Styling Xamarin.Forms Apps using XAML Styles
Introduction
Explicit Styles
Implicit Styles
Global Styles
Style Inheritance
Dynamic Styles
Device Styles
Styling Xamarin.Forms Apps using Cascading Style Sheets (CSS)
TableView
Text
Label
Entry
Editor
Fonts
Styles
Themes
Light Theme
Dark Theme
Creating a Custom Theme
Visual State Manager
WebView
Platform Features
Android
Android
AppCompat & Material Design
Application Indexing and Deep Linking
Device Class
iOS
Formatting
GTK#
Mac
Native Forms
Native Views
Native Views in XAML
Native Views in C#
Platform Specifics
Consuming Platform-Specifics
iOS
Android
Windows
Creating Platform-Specifics
Plugins
Tizen
Windows
Setup
WPF
Xamarin.Essentials
Getting Started
Accelerometer
App Information
Battery
Clipboard
Compass
Connectivity
Data Transfer
Device Display Information
Device Information
Email
File System Helpers
Flashlight
Geocoding
Geolocation
Gyroscope
Magnetometer
Main Thread
Open Browser
Orientation Sensor
Phone Dialer
Power
Preferences
Screen Lock
Secure Storage
SMS
Text-to-Speech
Version Tracking
Vibrate
Troubleshooting
Data & Cloud Services
Understanding the Sample
Consuming Web Services
ASMX
WCF
REST
Azure Mobile Apps
Authenticating Access to Web Services
REST
OAuth
Azure Mobile Apps
Azure Active Directory B2C
Integrating Azure Active Directory B2C with Azure Mobile Apps
Synchronizing Data with Web Services
Azure Mobile Apps
Sending Push Notifications
Azure
Storing Files in the Cloud
Azure Storage
Searching Data in the Cloud
Azure Search
Storing Data in a Document Database
Consuming an Azure Cosmos DB Document Database
Authenticating Users with an Azure Cosmos DB Document Database
Adding Intelligence with Cognitive Services
Speech Recognition
Spell Check
Text Translation
Emotion Recognition
Deployment & Testing
Performance
Xamarin.UITest and Test Cloud
Advanced Concepts and Internals
Fast Renderers
.NET Standard
Dependency Resolution
Troubleshooting
Frequently Asked Questions
Can I update the Xamarin.Forms default template to a newer NuGet package?
Why doesn't the Visual Studio XAML designer work for Xamarin.Forms XAML
files?
Android build error: The "LinkAssemblies" task failed unexpectedly
Why does my Xamarin.Forms.Maps Android project fail with COMPILETODALVIK
: UNEXPECTED TOP-LEVEL ERROR?
Release Notes
Samples
Creating Mobile Apps with Xamarin.Forms Book
Enterprise Application Patterns eBook
Getting Started with Xamarin.Forms
6/8/2018 • 2 minutes to read • Edit Online
Xamarin.Forms is a cross-platform UI toolkit that allows developers to efficiently create native user interface
layouts that can be shared across iOS, Android, and Universal Windows Platform apps. This series introduces the
basics of Xamarin.Forms development and covers building multi-platform and multi-screen applications.
For an overview of the installation and setup practices that apply to cross-platform development, see
Xamarin.Forms Requirements and Installation.
Xamarin.Forms Quickstart
Requirements
Overview of the platform requirements for Xamarin.Forms-developed apps, and the minimum system
requirements for developing with Xamarin.Forms in Visual Studio for Mac and Visual Studio.
Hello, Xamarin.Forms
This guide provides an introduction to developing a Xamarin.Forms application using Visual Studio for Mac or
Visual Studio. Topics covered include the tools, concepts, and steps required to build and deploy a Xamarin.Forms
application.
Introduction To Xamarin.Forms
This article discusses some of the key concepts for developing applications using Xamarin.Forms, including Views
and Layouts, the ListView control, Data Binding and Navigation.
Related Links
Free Self-Guided Learning (video)
Getting Started with Xamarin (video)
Hello, Xamarin.Forms iOS Workbook
Xamarin.Forms Requirements
5/23/2018 • 2 minutes to read • Edit Online
Target platforms
Xamarin.Forms applications can be written for the following operating systems:
iOS 8 or higher
Android 4.0.3 (API 15) or higher (more details)
Windows 10 Universal Windows Platform (more details)
It is assumed that developers have familiarity with .NET Standard and Shared Projects.
Additional platform support
The status of these platforms is available on the Xamarin.Forms GitHub:
Samsung Tizen
macOS
GTK#
WPF
Platforms from earlier versions
These platforms are not supported when using Xamarin.Forms 3.0:
Windows 8.1 / Windows Phone 8.1 WinRT
Windows Phone 8 Silverlight
Android
You should have the latest Android SDK Tools and Android API platform installed. You can update to the latest
versions using the Android SDK Manager.
Additionally, the target/compile version for Android projects must be set to Use latest installed platform. However
the minimum version can be set to API 15 so you can continue to support devices that use Android 4.0.3 and
newer. These values are set in the Project Options:
Visual Studio
Visual Studio for Mac
Project Options > Application > Application Properties
Development system requirements
Xamarin.Forms apps can be developed on macOS and Windows. However, Windows and Visual Studio are
required to produce Windows versions of the app.
NOTE
Windows apps cannot be developed on macOS.
This guide provides an introduction to developing a Xamarin.Forms application using Visual Studio for Mac or
Visual Studio, and to the fundamentals of application development using Xamarin.Forms. Topics covered include
the tools, concepts, and steps required to build and deploy a Xamarin.Forms application.
Start by reviewing the Xamarin.Forms System Requirements.
Part 1: Quickstart
The first part of this guide demonstrates how to create an application that translates an alphanumeric phone
number entered by the user into a numeric phone number, and then calls that number.
Related Links
Introduction to Xamarin.Forms
Debugging in Visual Studio
Visual Studio for Mac Recipes - Debugging
Free Self-Guided Learning (video)
Getting Started with Xamarin (video)
Hello, Xamarin.Forms iOS Workbook
Xamarin.Forms Quickstart
7/25/2018 • 14 minutes to read • Edit Online
This walkthrough demonstrates how to create an application that translates an alphanumeric phone number
entered by the user into a numeric phone number, and that calls the number. The final application is shown below:
NOTE
Failing to name the solution Phoneword will result in numerous build errors.
4. In the New Cross Platform App dialog, click Blank App, select .NET Standard as the Code Sharing
Strategy, and click the OK button:
Save the changes to MainPage.xaml by pressing CTRL+S, and close the file.
7. In Solution Explorer, expand MainPage.xaml and double-click MainPage.xaml.cs to open it:
8. In MainPage.xaml.cs, remove all of the template code and replace it with the following code. The
OnTranslate and OnCall methods will be executed in response to the Translate and Call buttons being
clicked in the user interface, respectively:
using System;
using Xamarin.Forms;
namespace Phoneword
{
public partial class MainPage : ContentPage
{
string translatedNumber;
public MainPage ()
{
InitializeComponent ();
}
NOTE
Attempting to build the application at this point will result in errors that will be fixed later.
Save the changes to MainPage.xaml.cs by pressing CTRL+S, and close the file.
9. In Solution Explorer, right click on the Phoneword project and select Add > New Item...:
10. In the Add New Item dialog, select Visual C# > Code > Class, name the new file PhoneTranslator, and
click the Add button:
11. In PhoneTranslator.cs, remove all of the template code and replace it with the following code. This code
will translate a phone word to a phone number:
using System.Text;
namespace Phoneword
{
public static class PhonewordTranslator
{
public static string ToNumber(string raw)
{
if (string.IsNullOrWhiteSpace(raw))
return null;
raw = raw.ToUpperInvariant();
Save the changes to PhoneTranslator.cs by pressing CTRL+S, and close the file.
12. In Solution Explorer, right click on the Phoneword project and select Add > New Item...:
13. In the Add New Item dialog, select Visual C# > Code > Interface, name the new file IDialer, and click
the Add button:
14. In IDialer.cs, remove all of the template code and replace it with the following code. This code defines a
Dial method that must be implemented on each platform to dial a translated phone number:
namespace Phoneword
{
public interface IDialer
{
bool Dial(string number);
}
}
Save the changes to IDialer.cs by pressing CTRL+S, and close the file.
NOTE
The common code for the application is now complete. Platform-specific phone dialer code will now be implemented
as a DependencyService.
15. In Solution Explorer, right click on the Phoneword.iOS project and select Add > New Item...:
16. In the Add New Item dialog, select Apple > Code > Class, name the new file PhoneDialer, and click the
Add button:
17. In PhoneDialer.cs, remove all of the template code and replace it with the following code. This code
creates the Dial method that will be used on the iOS platform to dial a translated phone number:
using Foundation;
using Phoneword.iOS;
using UIKit;
using Xamarin.Forms;
[assembly: Dependency(typeof(PhoneDialer))]
namespace Phoneword.iOS
{
public class PhoneDialer : IDialer
{
public bool Dial(string number)
{
return UIApplication.SharedApplication.OpenUrl (
new NSUrl ("tel:" + number));
}
}
}
Save the changes to PhoneDialer.cs by pressing CTRL+S, and close the file.
18. In Solution Explorer, right click on the Phoneword.Android project and select Add > New Item...:
19. In the Add New Item dialog, select Visual C# > Android > Class, name the new file PhoneDialer, and
click the Add button:
20. In PhoneDialer.cs, remove all of the template code and replace it with the following code. This code
creates the Dial method that will be used on the Android platform to dial a translated phone number:
using Android.Content;
using Android.Telephony;
using Phoneword.Droid;
using System.Linq;
using Xamarin.Forms;
using Uri = Android.Net.Uri;
[assembly: Dependency(typeof(PhoneDialer))]
namespace Phoneword.Droid
{
public class PhoneDialer : IDialer
{
public bool Dial(string number)
{
var context = MainActivity.Instance;
if (context == null)
return false;
return false;
}
if (list.Any ())
return true;
Note that this code assumes that you are using the latest Android API. Save the changes to
PhoneDialer.cs by pressing CTRL+S, and close the file.
21. In Solution Explorer, in the Phoneword.Android project, double-click MainActivity.cs to open it,
remove all of the template code and replace it with the following code:
using Android.App;
using Android.Content.PM;
using Android.OS;
namespace Phoneword.Droid
{
[Activity(Label = "Phoneword", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher =
true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
internal static MainActivity Instance { get; private set; }
base.OnCreate(bundle);
Instance = this;
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
}
}
Save the changes to MainActivity.cs by pressing CTRL+S, and close the file.
22. In Solution Explorer, in the Phoneword.Android project, double-click Properties and select the
Android Manifest tab:
23. In the Required permissions section, enable the CALL_PHONE permission. This gives the application
permission to place a phone call:
Save the changes to the manifest by pressing CTRL+S, and close the file.
24. In Solution Explorer, right click on the Phoneword.UWP project and select Add > New Item...:
25. In the Add New Item dialog, select Visual C# > Code > Class, name the new file PhoneDialer, and click
the Add button:
26. In PhoneDialer.cs, remove all of the template code and replace it with the following code. This code
creates the Dial method, and helper methods, that will be used on the Universal Windows Platform to dial
a translated phone number:
using Phoneword.UWP;
using System;
using System.Threading.Tasks;
using Windows.ApplicationModel.Calls;
using Windows.UI.Popups;
using Xamarin.Forms;
[assembly: Dependency(typeof(PhoneDialer))]
namespace Phoneword.UWP
{
public class PhoneDialer : IDialer
{
bool dialled = false;
Save the changes to PhoneDialer.cs by pressing CTRL+S, and close the file.
27. In Solution Explorer, in the Phoneword.UWP project, right-click References, and select Add
Reference...:
28. In the Reference Manager dialog, select Universal Windows > Extensions > Windows Mobile
Extensions for UWP, and click the OK button:
Save the changes to the manifest by pressing CTRL+S, and close the file.
31. In Visual Studio, select the Build > Build Solution menu item (or press CTRL+SHIFT+B ). The application
will build and a success message will appear in the Visual Studio status bar:
If there are errors, repeat the previous steps and correct any mistakes until the application builds
successfully.
32. In Solution Explorer, right click on the Phoneword.UWP project and select Set as StartUp Project:
33. In the Visual Studio toolbar, press the Start button (the triangular button that resembles a Play button) to
launch the application:
34. In Solution Explorer, right click on the Phoneword.Android project and select Set as StartUp Project.
35. In the Visual Studio toolbar, press the Start button (the triangular button that resembles a Play button) to
launch the application inside an Android emulator.
36. If you have an iOS device and meet the Mac system requirements for Xamarin.Forms development, use a
similar technique to deploy the app to the iOS device. Alternatively, deploy the app to the iOS remote
simulator.
Note: phone calls are not supported on all the simulators.
Congratulations on completing a Xamarin.Forms application. The next topic in this guide reviews the steps that
were taken in this walkthrough to gain an understanding of the fundamentals of application development using
Xamarin.Forms.
Related Links
Accessing Native Features via the DependencyService
Phoneword (sample)
Xamarin.Forms Deep Dive
7/25/2018 • 11 minutes to read • Edit Online
In the Xamarin.Forms Quickstart, the Phoneword application was built. This article reviews what has been built to
gain an understanding of the fundamentals of how Xamarin.Forms applications work.
Visual Studio
Visual Studio for Mac
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace Phoneword
{
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new MainPage();
}
...
}
}
This code sets the MainPage property of the App class to a new instance of the MainPage class. In addition, the
XamlCompilation attribute turns on the XAML compiler, so that XAML is compiled directly into intermediate
language. For more information, see XAML Compilation.
namespace Phoneword.iOS
{
[Register ("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init ();
LoadApplication (new App ());
return base.FinishedLaunching (app, options);
}
}
}
The FinishedLaunching override initializes the Xamarin.Forms framework by calling the Init method. This causes
the iOS -specific implementation of Xamarin.Forms to be loaded in the application before the root view controller
is set by the call to the LoadApplication method.
Android
To launch the initial Xamarin.Forms page in Android, the Phoneword.Droid project includes code that creates an
Activity with the MainLauncher attribute, with the activity inheriting from the FormsAppCompatActivity class, as
shown in the following code example:
namespace Phoneword.Droid
{
[Activity(Label = "Phoneword",
Icon = "@mipmap/icon",
Theme = "@style/MainTheme",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
internal static MainActivity Instance { get; private set; }
base.OnCreate(bundle);
Instance = this;
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
}
}
The OnCreate override initializes the Xamarin.Forms framework by calling the Init method. This causes the
Android-specific implementation of Xamarin.Forms to be loaded in the application before the Xamarin.Forms
application is loaded. In addition, the MainActivity class stores a reference to itself in the Instance property. The
Instance property is known as the local context, and is referenced from the PhoneDialer class.
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
...
}
This causes the UWP -specific implementation of Xamarin.Forms to be loaded in the application. The initial
Xamarin.Forms page is launched by the MainPage class, as demonstrated in the following code example:
namespace Phoneword.UWP
{
public sealed partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
this.LoadApplication(new Phoneword.App());
}
}
}
NOTE
Universal Windows Platform (UWP) apps can be built with Xamarin.Forms, but only using Visual Studio on Windows.
User Interface
There are four main control groups used to create the user interface of a Xamarin.Forms application.
1. Pages – Xamarin.Forms pages represent cross-platform mobile application screens. The Phoneword
application uses the ContentPage class to display a single screen. For more information about pages, see
Xamarin.Forms Pages.
2. Layouts – Xamarin.Forms layouts are containers used to compose views into logical structures. The
Phoneword application uses the StackLayout class to arrange controls in a horizontal stack. For more
information about layouts, see Xamarin.Forms Layouts.
3. Views – Xamarin.Forms views are the controls displayed on the user interface, such as labels, buttons, and text
entry boxes. The Phoneword application uses the Label , Entry , and Button controls. For more information
about views, see Xamarin.Forms Views.
4. Cells – Xamarin.Forms cells are specialized elements used for items in a list, and describe how each item in a
list should be drawn. The Phoneword application does not make use of any cells. For more information about
cells, see Xamarin.Forms Cells.
At runtime, each control will be mapped to its native equivalent, which is what will be rendered.
When the Phoneword application is run on any platform, it displays a single screen that corresponds to a Page in
Xamarin.Forms. A Page represents a ViewGroup in Android, a View Controller in iOS, or a Page on the Universal
Windows Platform. The Phoneword application also instantiates a ContentPage object that represents the
MainPage class, whose XAML markup is shown in the following code example:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Phoneword.MainPage">
...
<StackLayout>
<Label Text="Enter a Phoneword:" />
<Entry x:Name="phoneNumberText" Text="1-855-XAMARIN" />
<Button x:Name="translateButon" Text="Translate" Clicked="OnTranslate" />
<Button x:Name="callButton" Text="Call" IsEnabled="false" Clicked="OnCall" />
</StackLayout>
</ContentPage>
The MainPage class uses a StackLayout control to automatically arrange controls on the screen regardless of the
screen size. Each child element is positioned one after the other, vertically in the order in which they are added. The
StackLayout control contains a Label control to display text on the page, an Entry control to accept textual user
input, and two Button controls used to execute code in response to touch events.
For more information about XAML in Xamarin.Forms, see Xamarin.Forms XAML Basics.
Responding to User Interaction
An object defined in XAML can fire an event that is handled in the code-behind file. The following code example
shows the OnTranslate method in the code-behind for the MainPage class, which is executed in response to the
Clicked event firing on the Translate button.
The OnTranslate method translates the phoneword into its corresponding phone number, and in response, sets
properties on the call button. The code-behind file for a XAML class can access an object defined in XAML using
the name assigned to it with the x:Name attribute. The value assigned to this attribute has the same rules as C#
variables, in that it must begin with a letter or underscore and contain no embedded spaces.
The wiring of the translate button to the OnTranslate method occurs in the XAML markup for the MainPage class:
callButton.IsEnabled = false;
Displaying an alert dialog. When the user presses the call Button the Phoneword application shows an
Alert Dialog with the option to place or cancel a call. The DisplayAlert method is used to create the dialog,
as shown in the following code example:
await this.DisplayAlert (
"Dial a Number",
"Would you like to call " + translatedNumber + "?",
"Yes",
"No");
Accessing native features via the DependencyService class. The Phoneword application uses the
DependencyService class to resolve the IDialer interface to platform -specific phone dialing
implementations, as shown in the following code example from the Phoneword project:
For more information about the DependencyService class, see Accessing Native Features via the
DependencyService.
Placing a phone call with a URL. The Phoneword application uses OpenURL to launch the system phone app.
The URL consists of a tel: prefix followed by the phone number to be called, as shown in the following
code example from the iOS project:
Tweaking the platform layout. The Device class enables developers to customize the application layout and
functionality on a per-platform basis, as shown in the following code example that uses different Padding
values on different platforms to correctly display each page:
Summary
This article has examined the fundamentals of application development using Xamarin.Forms. Topics covered
included the anatomy of a Xamarin.Forms application, architecture and application fundamentals, and the user
interface.
In the next section of this guide the application will be extended to include multiple screens, to explore more
advanced Xamarin.Forms architecture and concepts.
Hello, Xamarin.Forms Multiscreen
7/25/2018 • 2 minutes to read • Edit Online
This guide expands the Phoneword application created in the Hello, Xamarin.Forms guide to navigate to a second
screen. Topics covered include page navigation and data binding to a collection.
Part 1: Quickstart
The first part of this guide demonstrates how to add a second screen to the Phoneword application to keep track of
the call history for the application.
Related Links
Introduction to Xamarin.Forms
Debugging in Visual Studio
Visual Studio for Mac Recipes - Debugging
Free Self-Guided Learning (video)
Getting Started with Xamarin (video)
Xamarin.Forms Multiscreen Quickstart
7/12/2018 • 6 minutes to read • Edit Online
This quickstart demonstrates how to extend the Phoneword application by adding a second screen to keep track of
the call history for the application. The final application is shown below:
3. In the Add New Item dialog, select Visual C# Items > Xamarin.Forms > Content Page, name the new
item CallHistoryPage, and click the Add button. This will add a page named CallHistoryPage to the
project:
4. In CallHistoryPage.xaml, remove all of the template code and replace it with the following code. This code
declaratively defines the user interface for the page:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:local="clr-namespace:Phoneword;assembly=Phoneword"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Phoneword.CallHistoryPage"
Title="Call History">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="20, 40, 20, 20" />
<On Platform="Android, UWP" Value="20" />
</OnPlatform>
</ContentPage.Padding>
<StackLayout>
<ListView ItemsSource="{x:Static local:App.PhoneNumbers}" />
</StackLayout>
</ContentPage>
Save the changes to CallHistoryPage.xaml by pressing CTRL+S, and close the file.
5. In Solution Explorer, double-click the App.xaml.cs file in the shared Phoneword project to open it:
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace Phoneword
{
public partial class App : Application
{
public static IList<string> PhoneNumbers { get; set; }
public App()
{
InitializeComponent();
PhoneNumbers = new List<string>();
MainPage = new NavigationPage(new MainPage());
}
...
}
}
Save the changes to App.xaml.cs by pressing CTRL+S, and close the file.
7. In Solution Explorer, double-click the MainPage.xaml file in the shared Phoneword project to open it:
8. In MainPage.xaml, add a Button control at the end of the StackLayout control. The button will be used to
navigate to the call history page:
<StackLayout VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
Orientation="Vertical"
Spacing="15">
...
<Button x:Name="callButton" Text="Call" IsEnabled="false" Clicked="OnCall" />
<Button x:Name="callHistoryButton" Text="Call History" IsEnabled="false"
Clicked="OnCallHistory" />
</StackLayout>
Save the changes to MainPage.xaml by pressing CTRL+S, and close the file.
9. In Solution Explorer, double-click MainPage.xaml.cs to open it:
10. In MainPage.xaml.cs, add the OnCallHistory event handler method, and modify the OnCall event
handler method to add the translated phone number to the App.PhoneNumbers collection and enable the
callHistoryButton , provided that the dialer variable is not null :
using System;
using Xamarin.Forms;
namespace Phoneword
{
public partial class MainPage : ContentPage
{
...
Save the changes to MainPage.xaml.cs by pressing CTRL+S, and close the file.
11. In Visual Studio, select the Build > Build Solution menu item (or press CTRL+SHIFT+B ). The application
will build and a success message will appear in the Visual Studio status bar:
If there are errors, repeat the previous steps and correct any mistakes until the application builds
successfully.
12. In the Visual Studio toolbar, press the Start button (the triangular button that resembles a Play button) to
launch the application:
13. In Solution Explorer, right click on the Phoneword.Droid project and select Set as StartUp Project.
14. In the Visual Studio toolbar, press the Start button (the triangular button that resembles a Play button) to
launch the application inside an Android emulator.
15. If you have an iOS device and meet the Mac system requirements for Xamarin.Forms development, use a
similar technique to deploy the app to the iOS device. Alternatively, deploy the app to the iOS remote
simulator.
Note: phone calls are not supported on all the simulators.
Congratulations on completing a multiscreen Xamarin.Forms application. The next topic in this guide reviews the
steps that were taken in this walkthrough to develop an understanding of page navigation and data binding using
Xamarin.Forms.
Related Links
Phoneword (sample)
PhonewordMultiscreen (sample)
Xamarin.Forms Multiscreen Deep Dive
7/12/2018 • 3 minutes to read • Edit Online
In the Xamarin.Forms Multiscreen Quickstart, the Phoneword application was extended to include a second screen
that keeps track of the call history for the application. This article reviews what has been built, to develop an
understanding of page navigation and data binding in a Xamarin.Forms application.
Navigation
Xamarin.Forms provides a built-in navigation model that manages the navigation and user-experience of a stack of
pages. This model implements a last-in, first-out (LIFO ) stack of Page objects. To move from one page to another
an application will push a new page onto this stack. To return back to the previous page the application will pop
the current page from the stack.
Xamarin.Forms has a NavigationPage class that manages the stack of Page objects. The NavigationPage class will
also add a navigation bar to the top of the page that displays a title and a platform-appropriate Back button that
will return to the previous page. The following code example shows how to wrap a NavigationPage around the
first page in an application:
public App ()
{
...
MainPage = new NavigationPage (new MainPage ());
}
All ContentPage instances have a Navigation property that exposes methods to modify the page stack. These
methods should only be invoked if the application includes a NavigationPage . To navigate to the CallHistoryPage ,
it is necessary to invoke the PushAsync method as demonstrated in the code example below:
This causes the new CallHistoryPage object to be pushed onto the Navigation stack. To programmatically return
back to the original page, the CallHistoryPage object must invoke the PopAsync method, as demonstrated in the
code example below:
await Navigation.PopAsync();
However, in the Phoneword application this code isn't required as the NavigationPage class adds a navigation bar
to the top of the page that includes a platform appropriate Back button that will return to the previous page.
Data Binding
Data binding is used to simplify how a Xamarin.Forms application displays and interacts with its data. It
establishes a connection between the user interface and the underlying application. The BindableObject class
contains much of the infrastructure to support data binding.
Data binding defines the relationship between two objects. The source object will provide data. The target object
will consume (and often display) the data from the source object. In the Phoneword application, the binding target
is the ListView control that displays phone numbers, while the PhoneNumbers collection is the binding source.
The PhoneNumbers collection is declared and initialized in the App class, as shown in the following code example:
public App ()
{
PhoneNumbers = new List<string>();
...
}
...
}
The ListView instance is declared and initialized in the CallHistoryPage class, as shown in the following code
example:
In this example, the ListView control will display the IEnumerable collection of data that the ItemsSource
property binds to. The collection of data can be objects of any type, but by default, ListView will use the ToString
method of each item to display that item. The x:Static markup extension is used to indicate that the ItemsSource
property will be bound to the static PhoneNumbers property of the App class, which can be located in the local
namespace.
For more information about data binding, see Data Binding Basics. For more information about XAML markup
extensions, see XAML Markup Extensions.
Summary
This article has introduced page navigation and data binding in a Xamarin.Forms application, and demonstrated
their use in a multi-screen cross-platform application.
An Introduction to Xamarin.Forms
7/12/2018 • 21 minutes to read • Edit Online
Xamarin.Forms is a cross-platform natively backed UI toolkit abstraction that allows developers to easily create
user interfaces that can be shared across Android, iOS, Windows, and the Universal Windows Platform. The user
interfaces are rendered using the native controls of the target platform, allowing Xamarin.Forms applications to
retain the appropriate look and feel for each platform. This article provides an introduction to Xamarin.Forms
and how to get started writing applications with it.
Overview
Xamarin.Forms is a framework that allows developers to rapidly create cross platform user interfaces. It provides
its own abstraction for the user interface that will be rendered using native controls on iOS, Android, or the
Universal Windows Platform (UWP ). This means that applications can share a large portion of their user
interface code and still retain the native look and feel of the target platform.
Xamarin.Forms allows for rapid prototyping of applications that can evolve over time to complex applications.
Because Xamarin.Forms applications are native applications, they don't have the limitations of other toolkits such
as browser sandboxing, limited APIs, or poor performance. Applications written using Xamarin.Forms are able to
utilize any of the API’s or features of the underlying platform, such as (but not limited to) CoreMotion, PassKit,
and StoreKit on iOS; NFC and Google Play Services on Android; and Tiles on Windows. In addition, it's possible
to create applications that will have parts of their user interface created with Xamarin.Forms while other parts
are created using the native UI toolkit.
Xamarin.Forms applications are architected in the same way as traditional cross-platform applications. The most
common approach is to use Portable Libraries or Shared Projects to house the shared code, and create platform
specific applications that will consume the shared code.
There are two techniques to create user interfaces in Xamarin.Forms. The first technique is to create UIs entirely
with C# source code. The second technique is to use Extensible Application Markup Language (XAML ), a
declarative markup language that is used to describe user interfaces. For more information about XAML, see
XAML Basics.
This article discusses the fundamentals of the Xamarin.Forms framework, and covers the following topics:
Examining a Xamarin.Forms application.
How Xamarin.Forms pages and controls are used.
How to use display a list of data.
How to set up data binding.
How to navigate between pages.
Next steps.
Examining a Xamarin.Forms Application
In Visual Studio for Mac and Visual Studio, the default Xamarin.Forms app template creates the simplest
Xamarin.Forms solution possible, which displays text to the user. If you run the application, it should appear
similar to the following screenshots:
Each screen in the screenshots corresponds to a Page in Xamarin.Forms. A Page represents an Activity in
Android, a View Controller in iOS, or a Page in the Windows Universal Platform (UWP ). The sample in the
screenshots above instantiates a ContentPage object and uses that to display a Label .
To maximize the reuse of the startup code, Xamarin.Forms applications have a single class named App that is
responsible for instantiating the first Page that will be displayed. An example of the App class can be seen in the
following code:
This code instantiates a new ContentPage object that will display a single Label centered both vertically and
horizontally on the page.
Launching the Initial Xamarin.Forms Page on Each Platform
To use this Page inside an application, each platform application must initialize the Xamarin.Forms framework
and provide an instance of the ContentPage as it is starting up. This initialization step varies from platform to
platform and is discussed in the following sections.
iOS
To launch the initial Xamarin.Forms page in iOS, the platform project includes the AppDelegate class that inherits
from the Xamarin.Forms.Platform.iOS.FormsApplicationDelegate class, as demonstrated in the following code
example:
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init ();
LoadApplication (new App ());
return base.FinishedLaunching (app, options);
}
}
The FinishedLoading override initializes the Xamarin.Forms framework by calling the Init method. This causes
the iOS -specific implementation of Xamarin.Forms to be loaded in the application before the root view controller
is set by the call to the LoadApplication method.
Android
To launch the initial Xamarin.Forms page in Android, the platform project includes code that creates an Activity
with the MainLauncher attribute, with the activity inherting from the FormsAppCompatActivity class, as
demonstrated in the following code example:
namespace HelloXamarinFormsWorld.Android
{
[Activity(Label = "HelloXamarinFormsWorld", Theme = "@style/MainTheme", MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication (new App ());
}
}
}
The OnCreate override initializes the Xamarin.Forms framework by calling the Init method. This causes the
Android-specific implementation of Xamarin.Forms to be loaded in the application before the Xamarin.Forms
application is loaded.
Universal Windows Platform
In Universal Windows Platform (UWP ) applications, the Init method that initializes the Xamarin.Forms
framework is invoked from the App class:
Xamarin.Forms.Forms.Init (e);
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
...
}
This causes the UWP -specific implementation of Xamarin.Forms to be loaded in the application. The initial
Xamarin.Forms page is launched by the MainPage class, as demonstrated in the following code example:
public partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
this.LoadApplication(new HelloXamarinFormsWorld.App());
}
}
By default the StackLayout assumes a vertical orientation as shown in the following screenshots:
The orientation of the StackLayout can be changed to a horizontal orientation, as demonstrated in the following
XAML code example:
The size of controls can be set through the HeightRequest and WidthRequest properties, as demonstrated in the
following XAML code example:
Lists in Xamarin.Forms
The ListView control is responsible for displaying a collection of items on the screen – each item in the
ListView will be contained in a single cell. By default, a ListView will use the built-in TextCell template and
render a single line of text.
The following code example shows a simple ListView example:
var listView = new ListView
{
RowHeight = 40
};
listView.ItemsSource = new string []
{
"Buy pears", "Buy oranges", "Buy mangos", "Buy apples", "Buy bananas"
};
Content = new StackLayout
{
VerticalOptions = LayoutOptions.FillAndExpand,
Children = { listView }
};
The ListView control can be populated as demonstrated in the following code example:
This creates a binding that specifies the path to the TodoItem.Name property, and will result in the previously
displayed screenshot.
For more information about binding to a custom class, see ListView Data Sources.
Selecting an Item in a ListView
To respond to a user touching a cell in a ListView , the ItemSelected event should be handled, as demonstrated
in the following code example:
When contained within a NavigationPage , the PushAsync method can be used to open a new page with built-in
back-navigation. The ItemSelected event can access the object that was associated with the cell through the
e.SelectedItem property, bind it to a new page and display the new page using PushAsync , as demonstrated in
the following code example:
Each platform implements built-in back-navigation in its own way. For more information, see Navigation.
For more information about ListView selection, see ListView Interactivity.
Customizing the Appearance of a Cell
Cell appearance can be customized by subclassing the ViewCell class, and setting the type of this class to the
ItemTemplate property of the ListView .
The cell shown in the following screenshot is composed of one Image and two Label controls:
To create this custom layout, the ViewCell class should be subclassed, as demonstrated in the following code
example:
class EmployeeCell : ViewCell
{
public EmployeeCell()
{
var image = new Image
{
HorizontalOptions = LayoutOptions.Start
};
image.SetBinding(Image.SourceProperty, new Binding("ImageUri"));
image.WidthRequest = image.HeightRequest = 40;
This code will provide a List of Employee to the ListView . Each cell will be rendered using the EmployeeCell
class. The ListView will pass the Employee object to the EmployeeCell as its BindingContext .
For more information about customizing cell appearance, see Cell Appearance.
Using XAML to Create and Customize A List
The XAML equivalent of the ListView in the previous section is demonstrated in the following code example:
This XAML defines a ContentPage that contains a ListView . The data source of the ListView is set via the
ItemsSource attribute. The layout of each row in the ItemsSource is defined within the ListView.ItemTemplate
element.
Data Binding
Data binding connects two objects, called the source and the target. The source object provides the data. The
target object will consume (and often display) data from the source object. For example, a Label (target object)
will commonly bind its Text property to a public string property in a source object. The following diagram
illustrates the binding relationship:
The main benefit of data binding is that you no longer have to worry about synchronizing data between your
views and data source. Changes in the source object are automatically pushed to the target object behind-the-
scenes by the binding framework, and changes in the target object can be optionally pushed back to the source
object.
Establishing data binding is a two step process:
The BindingContext property of the target object must be set to the source.
A binding must be established between the target and the source. In XAML, this is achieved by using the
Binding markup extension. In C#, this is achieved by the SetBinding method.
For more information about data binding, see Data Binding Basics.
XAML
The following code shows an example of performing data binding in XAML:
A binding between the Entry.Text property and the FirstName property of the source object is established.
Changes made in the Entry control will automatically be propagated to the employeeToDisplay object. Similarly,
if changes are made to to the employeeToDisplay.FirstName property, the Xamarin.Forms binding engine will also
update the contents of the Entry control. This is known as a two -way binding. In order for two-way binding to
work, the model class must implement the INotifyPropertyChanged interface.
Although the BindingContext property of the EmployeeDetailPage class can be set in XAML, here it’s set in code-
behind to an instance of an Employee object:
While the BindingContext property of each target object can be individually set, this isn’t necessary.
BindingContext is a special property that’s inherited by all its children. Therefore, when the BindingContext on
the ContentPage is set to an Employee instance, all of the children of the ContentPage have the same
BindingContext , and can bind to public properties of the Employee object.
C#
The following code shows an example of performing data binding in C#:
The ContentPage constructor is passed an instance of an Employee object, and sets the BindingContext to the
object to bind to. An Entry control is instantiated, and the binding between the Entry.Text property and the
FirstName property of the source object is set. Changes made in the Entry control will automatically be
propagated to the employeeToDisplay object. Similarly, if changes are made to to the
employeeToDisplay.FirstName property, the Xamarin.Forms binding engine will also update the contents of the
Entry control. This is known as a two -way binding. In order for two-way binding to work, the model class must
implement the INotifyPropertyChanged interface.
The SetBinding method takes two parameters. The first parameter specifies information about the type of
binding. The second parameter is used to provide information about what to bind to or how to bind. The second
parameter is, in most cases, just a string holding the name of property on the BindingContext . The following
syntax is used to bind to the BindingContext directly:
The dot syntax tells Xamarin.Forms to use the BindingContext as the data source instead of a property on the
BindingContext . This is useful when the BindingContext is a simple type, such as a string or an int .
string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
if (value.Equals(_firstName, StringComparison.Ordinal))
{
// Nothing to do - the value hasn't changed;
return;
}
_firstName = value;
OnPropertyChanged();
}
}
When the MyObject.FirstName property changes, the OnPropertyChanged method is invoked, which will raise the
PropertyChanged event. To avoid unnecessary events firing, the PropertyChanged event isn't raised if the property
value doesn't change.
Note that in the OnPropertyChanged method the propertyName parameter is adorned with the CallerMemberName
attribute. This ensures that if the OnPropertyChanged method is invoked with a null value, the CallerMemberName
attribute will provide the name of the method that invoked OnPropertyChanged .
Navigation
Xamarin.Forms provides a number of different page navigation experiences, depending upon the Page type
being used. For ContentPage instances there are two navigation experiences:
Hierarchical Navigation
Modal Navigation
The CarouselPage , MasterDetailPage and TabbedPage classes provide alternative navigation experiences. For
more information, see Navigation.
Hierarchical Navigation
The NavigationPage class provides a hierarchical navigation experience where the user is able to navigate
through pages, forwards and backwards, as desired. The class implements navigation as a last-in, first-out (LIFO )
stack of Page objects.
In hierarchical navigation, the NavigationPage class is used to navigate through a stack of ContentPage objects.
To move from one page to another, an application will push a new page onto the navigation stack, where it will
become the active page. To return back to the previous page, the application will pop the current page from the
navigation stack, and the new topmost page becomes the active page.
The first page added to a navigation stack is referred to as the root page of the application, and the following
code example shows how this is accomplished:
public App ()
{
MainPage = new NavigationPage(new EmployeeListPage());
}
To navigate to the LoginPage , it is necessary to invoke the PushAsync method on the Navigation property of the
current page, as demonstrated in the following code example:
This causes the new LoginPage object to be pushed on the navigation stack, where it becomes the active page.
The active page can be popped from the navigation stack by pressing the Back button on the device, regardless
of whether this is a physical button on the device or an on-screen button. To programmatically return to the
previous page, the LoginPage instance must invoke the PopAsync method, as demonstrated in the following
code example:
await Navigation.PopAsync();
NOTE
A NavigationPage instance is not required for performing modal page navigation.
To modally navigate to the LoginPage it is necessary to invoke the PushModalAsync method on the Navigation
property of the current page, as demonstrated in the following code example:
This causes the LoginPage instance to be pushed onto the navigation stack, where it becomes the active page.
The active page can be popped from the navigation stack by pressing the Back button on the device, regardless
of whether this is a physical button on the device or an on-screen button. To programmatically return to the
original page, the LoginPage instance must invoke the PopModalAsync method, as demonstrated in the following
code example:
await Navigation.PopModalAsync();
This causes the LoginPage instance to be removed from the navigation stack, with the new topmost page
becoming the active page.
For more information about modal navigation, see Modal Pages.
Next Steps
This introductory article should enable you to start writing Xamarin.Forms applications. Suggested next steps
include reading about the following functionality:
Control templates provide the ability to easily theme and re-theme application pages at runtime. For more
information, see Control Templates.
Data templates provide the ability to define the presentation of data on supported controls. For more
information, see Data Templates.
Shared code can access native functionality through the DependencyService class. For more information, see
Accessing Native Features with DependencyService.
Xamarin.Forms includes a simple messaging service to send and receive messages, therefore reducing
coupling between classes. For more information, see Publish and Subscribe with MessagingCenter.
Each page, layout, and control is rendered differently on each platform using a Renderer class that in turn
creates a native control, arranges it on the screen, and adds the behavior specified in the shared code.
Developers can implement their own custom Renderer classes to customize the appearance and/or behavior
of a control. For more information, see Custom Renderers.
Effects also allow the native controls on each platform to be customized. Effects are created in platform-
specific projects by subclassing the PlatformEffect control, and are consumed by attaching them to an
appropriate Xamarin.Forms control. For more information, see Effects.
Alternatively, Creating Mobile Apps with Xamarin.Forms, a book by Charles Petzold, is a good place to learn
more about Xamarin.Forms. For more information, see Creating Mobile Apps with Xamarin.Forms.
Summary
This article provided an introduction to Xamarin.Forms and how to get started writing applications with it.
Xamarin.Forms is a cross-platform natively backed UI toolkit abstraction that allows developers to easily create
user interfaces that can be shared across Android, iOS, and the Universal Windows Platform. The user interfaces
are rendered using the native controls of the target platform, allowing Xamarin.Forms applications to retain the
appropriate look and feel for each platform.
Related Links
XAML Basics
Controls Reference
User Interface
Xamarin.Forms Samples
Getting Started Samples
Xamarin.Forms
Free Self-Guided Learning (video)
Hello, Xamarin.Forms iOS Workbook
eXtensible Application Markup Language (XAML)
7/12/2018 • 2 minutes to read • Edit Online
XAML is a declarative markup language that can be used to define user interfaces. The user interface is defined in
an XML file using the XAML syntax, while runtime behavior is defined in a separate code-behind file.
NOTE
Try out the XAML Standard Preview
XAML Basics
XAML allows developers to define user interfaces in Xamarin.Forms applications using markup rather than code.
XAML is never required in a Xamarin.Forms program but it is toolable, and is often more visually coherent and
more succinct than equivalent code. XAML is particularly well suited for use with the popular Model-View -
ViewModel (MVVM ) application architecture: XAML defines the View that is linked to ViewModel code through
XAML -based data bindings.
XAML Compilation
XAML can be optionally compiled directly into intermediate language (IL ) with the XAML compiler (XAMLC ). This
articles describes how to use XAMLC, and its benefits.
XAML Previewer
The XAML Previewer announced at Xamarin Evolve 2016 is available for testing in the Alpha channel.
XAML Namespaces
XAML uses the xmlns XML attribute for namespace declarations. This article introduces the XAML namespace
syntax, and demonstrates how to declare a XAML namespace to access a type.
Field Modifiers
The x:FieldModifier namespace attribute specifies the access level for generated fields for named XAML
elements.
Passing Arguments
XAML can be used to pass arguments to non-default constructors or to factory methods. This article demonstrates
using the XAML attributes that can be used to pass arguments to constructors, to call factory methods, and to
specify the type of a generic argument.
Bindable Properties
In Xamarin.Forms, the functionality of common language runtime (CLR ) properties is extended by bindable
properties. A bindable property is a special type of property, where the property's value is tracked by the
Xamarin.Forms property system. This article provides an introduction to bindable properties, and demonstrates
how to create and consume them.
Attached Properties
An attached property is a special type of bindable property, defined in one class but attached to other objects, and
recognizable in XAML as an attribute that contains a class and a property name separated by a period. This article
provides an introduction to attached properties, and demonstrates how to create and consume them.
Resource Dictionaries
XAML resources are definitions of objects that can be used more than once. A ResourceDictionary allows
resources to be defined in a single location, and re-used throughout a Xamarin.Forms application. This article
demonstrates how to create and consume a ResourceDictionary , and how to merge one ResourceDictionary into
another.
Xamarin.Forms XAML Basics
7/12/2018 • 3 minutes to read • Edit Online
XAML —the eXtensible Application Markup Language—allows developers to define user interfaces in
Xamarin.Forms applications using markup rather than code. XAML is never required in a Xamarin.Forms
program, but it is often more succinct and more visually coherent than equivalent code, and potentially toolable.
XAML is particularly well suited for use with the popular MVVM (Model-View -ViewModel) application
architecture: XAML defines the View that is linked to ViewModel code through XAML -based data bindings.
XAML topics are covered in more depth in many chapters of the book, including:
Overview
XAML is an XML -based language created by Microsoft as an alternative to programming code for instantiating
and initializing objects, and organizing those objects in parent-child hierarchies. XAML has been adapted to
several technologies within the .NET framework, but it has found its greatest utility in defining the layout of user
interfaces within the Windows Presentation Foundation (WPF ), Silverlight, the Windows Runtime, and the
Universal Windows Platform (UWP ).
XAML is also part of Xamarin.Forms, the cross-platform natively-based programming interface for iOS, Android,
and UWP mobile devices. Within the XAML file, the Xamarin.Forms developer can define user interfaces using all
the Xamarin.Forms views, layouts, and pages, as well as custom classes. The XAML file can be either compiled or
embedded in the executable. Either way, the XAML information is parsed at build time to locate named objects,
and again at runtime to instantiate and initialize objects, and to establish links between these objects and
programming code.
XAML has several advantages over equivalent code:
XAML is often more succinct and readable than equivalent code.
The parent-child hierarchy inherent in XML allows XAML to mimic with greater visual clarity the parent-child
hierarchy of user-interface objects.
XAML can be easily hand-written by programmers, but also lends itself to be toolable and generated by visual
design tools.
Of course, there are also disadvantages, mostly related to limitations that are intrinsic to markup languages:
XAML cannot contain code. All event handlers must be defined in a code file.
XAML cannot contain loops for repetitive processing. (However, several Xamarin.Forms visual objects—most
notably ListView —can generate multiple children based on the objects in its ItemsSource collection.)
XAML cannot contain conditional processing (However, a data-binding can reference a code-based binding
converter that effectively allows some conditional processing.)
XAML generally cannot instantiate classes that do not define a parameterless constructor. (However, there is
sometimes a way around this restriction.)
XAML generally cannot call methods. (Again, this restriction can sometimes be overcome.)
There is not yet a visual designer for generating XAML in Xamarin.Forms applications. All XAML must be hand-
written, but there is a XAML Previewer. Programmers new to XAML might want to frequently build and run their
applications, particularly after anything that might not be obviously correct. Even developers with lots of
experience in XAML know that experimentation is rewarding.
XAML is basically XML, but XAML has some unique syntax features. The most important are:
Property elements
Attached properties
Markup extensions
These features are not XML extensions. XAML is entirely legal XML. But these XAML syntax features use XML in
unique ways. They are discussed in detail in the articles below, which conclude with an introduction to using
XAML for implementing MVVM.
Requirements
This article assumes a working familiarity with Xamarin.Forms. Reading An Introduction to Xamarin.Forms is
highly recommended.
This article also assumes some familiarity with XML, including understanding the use of XML namespace
declarations, and the terms element, tag, and attribute.
When you're familiar with Xamarin.Forms and XML, start reading Part 1. Getting Started with XAML.
Related Links
XamlSamples
An Introduction to Xamarin.Forms
Creating Mobile Apps book
Xamarin.Forms Samples
Part 1. Getting Started with XAML
5/10/2018 • 15 minutes to read • Edit Online
In a Xamarin.Forms application, XAML is mostly used to define the visual contents of a page and works together
with a C# code-behind file.
The code-behind file provides code support for the markup. Together, these two files contribute to a new class
definition that includes child views and property initialization. Within the XAML file, classes and properties are
referenced with XML elements and attributes, and links between the markup and code are established.
Select a location for the solution, give it a name of XamlSamples (or whatever you prefer), and press OK.
On the next screen, select the Blank App template and the .NET Standard code-sharing strategy:
Press OK.
Four projects are created in the solution: the XamlSamples .NET Standard library, XamlSamples.Android,
XamlSamples.iOS, and the Universal Windows Platform solution, XamlSamples.UWP.
After creating the XamlSamples solution, you might want to test your development environment by selecting the
various platform projects as the solution startup project, and building and deploying the simple application
created by the project template on either phone emulators or real devices.
Unless you need to write platform-specific code, the shared XamlSamples .NET Standard library project is where
you’ll be spending virtually all of your programming time. These articles will not venture outside of that project.
Anatomy of a XAML File
Within the XamlSamples .NET Standard library are a pair of files with the following names:
App.xaml, the XAML file; and
App.xaml.cs, a C# code-behind file associated with the XAML file.
You'll need to click the arrow next to App.xaml to see the code-behind file.
Both App.xaml and App.xaml.cs contribute to a class named App that derives from Application . Most other
classes with XAML files contribute to a class that derives from ContentPage ; those files use XAML to define the
visual contents of an entire page. This is true of the other two files in the XamlSamples project:
MainPage.xaml, the XAML file; and
MainPage.xaml.cs, the C# code-behind file.
The MainPage.xaml file looks like this (although the formatting might be a little different):
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples"
x:Class="XamlSamples.MainPage">
<StackLayout>
<!-- Place new controls here -->
<Label Text="Welcome to Xamarin Forms!"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout>
</ContentPage>
The two XML namespace ( xmlns ) declarations refer to URIs, the first seemingly on Xamarin’s web site and the
second on Microsoft’s. Don’t bother checking what those URIs point to. There’s nothing there. They are simply
URIs owned by Xamarin and Microsoft, and they basically function as version identifiers.
The first XML namespace declaration means that tags defined within the XAML file with no prefix refer to classes
in Xamarin.Forms, for example ContentPage . The second namespace declaration defines a prefix of x . This is
used for several elements and attributes that are intrinsic to XAML itself and which are supported by other
implementations of XAML. However, these elements and attributes are slightly different depending on the year
embedded in the URI. Xamarin.Forms supports the 2009 XAML specification, but not all of it.
The local namespace declaration allows you to access other classes from the .NET Standard library project.
At the end of that first tag, the x prefix is used for an attribute named Class . Because the use of this x prefix is
virtually universal for the XAML namespace, XAML attributes such as Class are almost always referred to as
x:Class .
The x:Class attribute specifies a fully qualified .NET class name: the MainPage class in the XamlSamples
namespace. This means that this XAML file defines a new class named MainPage in the XamlSamples namespace
that derives from ContentPage —the tag in which the x:Class attribute appears.
The x:Class attribute can only appear in the root element of a XAML file to define a derived C# class. This is the
only new class defined in the XAML file. Everything else that appears in the XAML file is instead simply
instantiated from existing classes and initialized.
The MainPage.xaml.cs file looks like this (aside from unused using directives):
using Xamarin.Forms;
namespace XamlSamples
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
}
The MainPage class derives from ContentPage , but notice the partial class definition. This suggests that there
should be another partial class definition for MainPage , but where is it? And what is that InitializeComponent
method?
When Visual Studio builds the project, it parses the XAML file to generate a C# code file. If you look in the
XamlSamples\XamlSamples\obj\Debug directory, you’ll find a file named
XamlSamples.MainPage.xaml.g.cs. The ‘g’ stands for generated. This is the other partial class definition of
MainPage that contains the definition of the InitializeComponent method called from the MainPage constructor.
These two partial MainPage class definitions can then be compiled together. Depending on whether the XAML is
compiled or not, either the XAML file or a binary form of the XAML file is embedded in the executable.
At runtime, code in the particular platform project calls a LoadApplication method, passing to it a new instance of
the App class in the .NET Standard library. The App class constructor instantiates MainPage . The constructor of
that class calls InitializeComponent , which then calls the LoadFromXaml method that extracts the XAML file (or its
compiled binary) from the .NET Standard library. LoadFromXaml initializes all the objects defined in the XAML file,
connects them all together in parent-child relationships, attaches event handlers defined in code to events set in
the XAML file, and sets the resultant tree of objects as the content of the page.
Although you normally don’t need to spend much time with generated code files, sometimes runtime exceptions
are raised on code in the generated files, so you should be familiar with them.
When you compile and run this program, the Label element appears in the center of the page as the XAML
suggests. The three platforms from left to right are iOS, Android, and UWP:
For more interesting visuals, all you need is more interesting XAML.
Two files are added to the project, HelloXamlPage.xaml and the code-behind file HelloXamlPage.xaml.cs.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.HelloXamlPage">
<ContentPage.Content>
</ContentPage.Content>
</ContentPage>
The ContentPage.Content tags are part of the unique syntax of XAML. At first, they might appear to be invalid
XML, but they are legal. The period is not a special character in XML.
The ContentPage.Content tags are called property element tags. Content is a property of ContentPage , and is
generally set to a single view or a layout with child views. Normally properties become attributes in XAML, but it
would be hard to set a Content attribute to a complex object. For that reason, the property is expressed as an
XML element consisting of the class name and the property name separated by a period. Now the Content
property can be set between the ContentPage.Content tags, like this:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.HelloXamlPage"
Title="Hello XAML Page">
<ContentPage.Content>
</ContentPage.Content>
</ContentPage>
Also notice that a Title attribute has been set on the root tag.
At this time, the relationship between classes, properties, and XML should be evident: A Xamarin.Forms class
(such as ContentPage or Label ) appears in the XAML file as an XML element. Properties of that class—including
Title on ContentPage and seven properties of Label —usually appear as XML attributes.
Many shortcuts exist to set the values of these properties. Some properties are basic data types: For example, the
Title and Text properties are of type String , Rotation is of type Double , and IsVisible (which is true by
default and is set here only for illustration) is of type Boolean .
The HorizontalTextAlignment property is of type TextAlignment , which is an enumeration. For a property of any
enumeration type, all you need supply is a member name.
For properties of more complex types, however, converters are used for parsing the XAML. These are classes in
Xamarin.Forms that derive from TypeConverter . Many are public classes but some are not. For this particular
XAML file, several of these classes play a role behind the scenes:
LayoutOptionsConverter for the VerticalOptions property
FontSizeConverter for the FontSize property
ColorTypeConverter for the TextColor property
Each of the little letters is a hexadecimal digit. Here is how an alpha channel is included:
TextColor="#aarrggbb">
For the alpha channel, keep in mind that FF is fully opaque and 00 is fully transparent.
Two other formats allow you to specify only a single hexadecimal digit for each channel:
TextColor="#rgb" TextColor="#argb"
In these cases, the digit is repeated to form the value. For example, #CF3 is the RGB color CC -FF -33.
Page Navigation
When you run the XamlSamples program, the MainPage is displayed. To see the new HelloXamlPage you can
either set that as the new startup page in the App.xaml.cs file, or navigate to the new page from MainPage .
To implement navigation, first change code in the App.xaml.cs constructor so that a NavigationPage object is
created:
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
In the MainPage.xaml.cs constructor, you can create a simple Button and use the event handler to navigate to
HelloXamlPage :
public MainPage()
{
InitializeComponent();
Content = button;
}
Setting the Content property of the page replaces the setting of the Content property in the XAML file. When
you compile and deploy the new version of this program, a button appears on the screen. Pressing it navigates to
HelloXamlPage . Here’s the resultant page on iPhone, Android, and UWP:
You can navigate back to MainPage using the < Back button on iOS, using the left arrow at the top of the page or
at the bottom of the phone on Android, or using the left arrow at the top of the page on Windows 10.
Feel free to experiment with the XAML for different ways to render the Label . If you need to embed any Unicode
characters into the text, you can use the standard XML syntax. For example, to put the greeting in smart quotes,
use:
<Label Text="“Hello, XAML!”" … />
This XAML file is syntactically complete, and here’s what it looks like:
However, you are likely to consider this program to be functionally deficient. Perhaps the Slider is supposed to
cause the Label to display the current value, and the Button is probably intended to do something within the
program.
As you’ll see in Part 4. Data Binding Basics, the job of displaying a Slider value using a Label can be handled
entirely in XAML with a data binding. But it is useful to see the code solution first. Even so, handling the Button
click definitely requires code. This means that the code-behind file for XamlPlusCodePage must contain handlers for
the ValueChanged event of the Slider and the Clicked event of the Button . Let’s add them:
namespace XamlSamples
{
public partial class XamlPlusCodePage
{
public XamlPlusCodePage()
{
InitializeComponent();
}
}
}
}
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.XamlPlusCodePage"
Title="XAML + Code Page">
<StackLayout>
<Slider VerticalOptions="CenterAndExpand"
ValueChanged="OnSliderValueChanged" />
Notice that assigning a handler to an event has the same syntax as assigning a value to a property.
If the handler for the ValueChanged event of the Slider will be using the Label to display the current value, the
handler needs to reference that object from code. The Label needs a name, which is specified with the x:Name
attribute.
<Label x:Name="valueLabel"
Text="A simple Label"
Font="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
The x prefix of the x:Name attribute indicates that this attribute is intrinsic to XAML.
The name you assign to the x:Name attribute has the same rules as C# variable names. For example, it must begin
with a letter or underscore and contain no embedded spaces.
Now the ValueChanged event handler can set the Label to display the new Slider value. The new value is
available from the event arguments:
Or, the handler could obtain the Slider object that is generating this event from the sender argument and
obtain the Value property from that:
When you first run the program, the Label doesn’t display the Slider value because the ValueChanged event
hasn’t yet fired. But any manipulation of the Slider causes the value to be displayed:
Now for the Button . Let’s simulate a response to a Clicked event by displaying an alert with the Text of the
button. The event handler can safely cast the sender argument to a Button and then access its properties:
The method is defined as async because the DisplayAlert method is asynchronous and should be prefaced with
the await operator, which returns when the method completes. Because this method obtains the Button firing
the event from the sender argument, the same handler could be used for multiple buttons.
You’ve seen that an object defined in XAML can fire an event that is handled in the code-behind file, and that the
code-behind file can access an object defined in XAML using the name assigned to it with the x:Name attribute.
These are the two fundamental ways that code and XAML interact.
Some additional insights into how XAML works can be gleaned by examining the newly generated
XamlPlusCode.xaml.g.cs file, which now includes any name assigned to any x:Name attribute as a private field.
Here's a simplified version of that file:
The declaration of this field allows the variable to be freely used anywhere within the XamlPlusCodePage partial
class file under your jurisdiction. At runtime, the field is assigned after the XAML has been parsed. This means that
the valueLabel field is null when the XamlPlusCodePage constructor begins but valid after InitializeComponent
is called.
After InitializeComponent returns control back to the constructor, the visuals of the page have been constructed
just as if they had been instantiated and initialized in code. The XAML file no longer plays any role in the class. You
can manipulate these objects on the page in any way that you want, for example, by adding views to the
StackLayout , or setting the Content property of the page to something else entirely. You can “walk the tree” by
examining the Content property of the page and the items in the Children collections of layouts. You can set
properties on views accessed in this way, or assign event handlers to them dynamically.
Feel free. It’s your page, and XAML is only a tool to build its content.
Summary
With this introduction, you’ve seen how a XAML file and code file contribute to a class definition, and how the
XAML and code files interact. But XAML also has its own unique syntactical features that allow it to be used in a
very flexible manner. You can begin exploring these in Part 2. Essential XAML Syntax.
Related Links
XamlSamples
Part 2. Essential XAML Syntax
Part 3. XAML Markup Extensions
Part 4. Data Binding Basics
Part 5. From Data Binding to MVVM
Part 2. Essential XAML Syntax
6/20/2018 • 9 minutes to read • Edit Online
XAML is mostly designed for instantiating and initializing objects. But often, properties must be set to complex
objects that cannot easily be represented as XML strings, and sometimes properties defined by one class must be
set on a child class. These two needs require the essential XAML syntax features of property elements and
attached properties.
Property Elements
In XAML, properties of classes are normally set as XML attributes:
However, there is an alternative way to set a property in XAML. To try this alternative with TextColor , first delete
the existing TextColor setting:
Open up the empty-element Label tag by separating it into start and end tags:
</Label>
Within these tags, add start and end tags that consist of the class name and a property name separated by a
period:
</Label.TextColor>
</Label>
Set the property value as content of these new tags, like this:
<Label Text="Hello, XAML!"
VerticalOptions="Center"
FontAttributes="Bold"
FontSize="Large">
<Label.TextColor>
Aqua
</Label.TextColor>
</Label>
These two ways to specify the TextColor property are functionally equivalent, but don't use the two ways for the
same property because that would effectively be setting the property twice, and might be ambiguous.
With this new syntax, some handy terminology can be introduced:
Label is an object element. It is a Xamarin.Forms object expressed as an XML element.
Text , VerticalOptions , FontAttributes and FontSize are property attributes. They are Xamarin.Forms
properties expressed as XML attributes.
In that final snippet, TextColor has become a property element. It is a Xamarin.Forms property but it is now
an XML element.
The definition of property elements might at first seem to be a violation of XML syntax, but it’s not. The period has
no special meaning in XML. To an XML decoder, Label.TextColor is simply a normal child element.
In XAML, however, this syntax is very special. One of the rules for property elements is that nothing else can
appear in the Label.TextColor tag. The value of the property is always defined as content between the property-
element start and end tags.
You can use property-element syntax on more than one property:
At first, property-element syntax might seem like an unnecessary long-winded replacement for something
comparatively quite simple, and in these examples that is certainly the case.
However, property-element syntax becomes essential when the value of a property is too complex to be expressed
as a simple string. Within the property-element tags you can instantiate another object and set its properties. For
example, you can explicitly set a property such as VerticalOptions to a LayoutOptions value with property
settings:
<Label>
...
<Label.VerticalOptions>
<LayoutOptions Alignment="Center" />
</Label.VerticalOptions>
</Label>
Another example: The Grid has two properties named RowDefinitions and ColumnDefinitions . These two
properties are of type RowDefinitionCollection and ColumnDefinitionCollection , which are collections of
RowDefinition and ColumnDefinition objects. You need to use property element syntax to set these collections.
Here’s the beginning of the XAML file for a GridDemoPage class, showing the property element tags for the
RowDefinitions and ColumnDefinitions collections:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.GridDemoPage"
Title="Grid Demo Page">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
...
</Grid>
</ContentPage>
Notice the abbreviated syntax for defining auto-sized cells, cells of pixel widths and heights, and star settings.
Attached Properties
You've just seen that the Grid requires property elements for the RowDefinitions and ColumnDefinitions
collections to define the rows and columns. However, there must also be some way for the programmer to
indicate the row and column where each child of the Grid resides.
Within the tag for each child of the Grid you specify the row and column of that child using the following
attributes:
Grid.Row
Grid.Column
The default values of these attributes are 0. You can also indicate if a child spans more than one row or column
with these attributes:
Grid.RowSpan
Grid.ColumnSpan
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<BoxView Color="Silver"
HeightRequest="0"
Grid.Row="0" Grid.Column="1" />
<BoxView Color="Teal"
Grid.Row="1" Grid.Column="0" />
</Grid>
</ContentPage>
The Grid.Row and Grid.Column settings of 0 are not required but are generally included for purposes of clarity.
Here’s what it looks like on all three platforms:
Judging solely from the syntax, these Grid.Row , Grid.Column , Grid.RowSpan , and Grid.ColumnSpan attributes
appear to be static fields or properties of Grid , but interestingly enough, Grid does not define anything named
Row , Column , RowSpan , or ColumnSpan .
Instead, Griddefines four bindable properties named RowProperty , ColumnProperty , RowSpanProperty , and
ColumnSpanProperty . These are special types of bindable properties known as attached properties. They are
defined by the Grid class but set on children of the Grid .
When you wish to use these attached properties in code, the Grid class provides static methods named SetRow ,
GetColumn , and so forth. But in XAML, these attached properties are set as attributes in the children of the Grid
using simple properties names.
Attached properties are always recognizable in XAML files as attributes containing both a class and a property
name separated by a period. They are called attached properties because they are defined by one class (in this
case, Grid ) but attached to other objects (in this case, children of the Grid ). During layout, the Grid can
interrogate the values of these attached properties to know where to place each child.
The AbsoluteLayout class defines two attached properties named LayoutBounds and LayoutFlags . Here’s a
checkerboard pattern realized using the proportional positioning and sizing features of AbsoluteLayout :
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.AbsoluteDemoPage"
Title="Absolute Demo Page">
<AbsoluteLayout BackgroundColor="#FF8080">
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="0.33, 0, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="1, 0, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="0, 0.33, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="0.67, 0.33, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="0.33, 0.67, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="1, 0.67, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="0, 1, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="0.67, 1, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
</AbsoluteLayout>
</ContentPage>
Content Properties
In the previous examples, the StackLayout , Grid , and AbsoluteLayout objects are set to the Content property of
the ContentPage , and the children of these layouts are actually items in the Children collection. Yet these
Content and Children properties are nowhere in the XAML file.
You can certainly include the Content and Children properties as property elements, such as in the
XamlPlusCode sample:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.XamlPlusCodePage"
Title="XAML + Code Page">
<ContentPage.Content>
<StackLayout>
<StackLayout.Children>
<Slider VerticalOptions="CenterAndExpand"
ValueChanged="OnSliderValueChanged" />
<Label x:Name="valueLabel"
Text="A simple Label"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
The real question is: Why are these property elements not required in the XAML file?
Elements defined in Xamarin.Forms for use in XAML are allowed to have one property flagged in the
ContentProperty attribute on the class. If you look up the ContentPage class in the online Xamarin.Forms
documentation, you’ll see this attribute:
[Xamarin.Forms.ContentProperty("Content")]
public class ContentPage : TemplatedPage
This means that the Content property-element tags are not required. Any XML content that appears between the
start and end ContentPage tags is assumed to be assigned to the Content property.
StackLayout , Grid , AbsoluteLayout , and RelativeLayout all derive from Layout<View> , and if you look up
Layout<T> in the Xamarin.Forms documentation, you’ll see another ContentProperty attribute:
[Xamarin.Forms.ContentProperty("Children")]
public abstract class Layout<T> : Layout ...
That allows content of the layout to be automatically added to the Children collection without explicit Children
property-element tags.
Other classes also have ContentProperty attribute definitions. For example, the content property of Label is
Text . Check the API documentation for others.
You can also do something similar in XAML using the OnPlatform and On classes. First include property
elements for the Padding property near the top of the page:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
</ContentPage.Padding>
...
</ContentPage>
Within these tags, include an OnPlatform tag. OnPlatform is a generic class. You need to specify the generic type
argument, in this case, Thickness , which is the type of Padding property. Fortunately, there’s a XAML attribute
specifically to define generic arguments called x:TypeArguments . This should match the type of the property you're
setting:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
</OnPlatform>
</ContentPage.Padding>
...
</ContentPage>
OnPlatform has a property named Platforms that is an IList of On objects. Use property element tags for that
property:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<OnPlatform.Platforms>
</OnPlatform.Platforms>
</OnPlatform>
</ContentPage.Padding>
...
</ContentPage>
Now add On elements. For each one set the Platform property and the Value property to markup for the
Thickness property:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<OnPlatform.Platforms>
<On Platform="iOS" Value="0, 20, 0, 0" />
<On Platform="Android" Value="0, 0, 0, 0" />
<On Platform="UWP" Value="0, 0, 0, 0" />
</OnPlatform.Platforms>
</OnPlatform>
</ContentPage.Padding>
...
</ContentPage>
This markup can be simplified. The content property of OnPlatform is Platforms , so those property-element tags
can be removed:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0, 20, 0, 0" />
<On Platform="Android" Value="0, 0, 0, 0" />
<On Platform="UWP" Value="0, 0, 0, 0" />
</OnPlatform>
</ContentPage.Padding>
...
</ContentPage>
The Platform property of On is of type IList<string> , so you can include multiple platforms if the values are
the same:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0, 20, 0, 0" />
<On Platform="Android, UWP" Value="0, 0, 0, 0" />
</OnPlatform>
</ContentPage.Padding>
...
</ContentPage>
Because Android and UWP are set to the default value of Padding , that tag can be removed:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0, 20, 0, 0" />
</OnPlatform>
</ContentPage.Padding>
...
</ContentPage>
This is the standard way to set a platform-dependent Padding property in XAML. If the Value setting cannot be
represented by a single string, you can define property elements for it:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS">
<On.Value>
0, 20, 0, 0
</On.Value>
</On>
</OnPlatform>
</ContentPage.Padding>
...
</ContentPage>
Summary
With property elements and attached properties, much of the basic XAML syntax has been established. However,
sometimes you need to set properties to objects in an indirect manner, for example, from a resource dictionary.
This approach is covered in the next part, Part 3. XAML Markup Extensions.
Related Links
XamlSamples
Part 1. Getting Started with XAML
Part 3. XAML Markup Extensions
Part 4. Data Binding Basics
Part 5. From Data Binding to MVVM
Part 3. XAML Markup Extensions
7/9/2018 • 11 minutes to read • Edit Online
XAML markup extensions constitute an important feature in XAML that allow properties to be set to objects or
values that are referenced indirectly from other sources. XAML markup extensions are particularly important for
sharing objects, and referencing constants used throughout an application, but they find their greatest utility in
data bindings.
Shared Resources
Some XAML pages contain several views with properties set to the same values. For example, many of the
property settings for these Button objects are the same:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.SharedResourcesPage"
Title="Shared Resources Page">
<StackLayout>
<Button Text="Do this!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
BorderWidth="3"
Rotation="-15"
TextColor="Red"
FontSize="24" />
</StackLayout>
</ContentPage>
If one of these properties needs to be changed, you might prefer to make the change just once rather than three
times. If this were code, you’d likely be using constants and static read-only objects to help keep such values
consistent and easy to modify.
In XAML, one popular solution is to store such values or objects in a resource dictionary. The VisualElement
class defines a property named Resources of type ResourceDictionary , which is a dictionary with keys of type
string and values of type object . You can put objects into this dictionary and then reference them from
markup, all in XAML.
To use a resource dictionary on a page, include a pair of Resources property-element tags. It’s most convenient
to put these at the top of the page:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.SharedResourcesPage"
Title="Shared Resources Page">
<ContentPage.Resources>
</ContentPage.Resources>
...
</ContentPage>
<ContentPage.Resources>
<ResourceDictionary>
</ResourceDictionary>
</ContentPage.Resources>
...
</ContentPage>
Now objects and values of various types can be added to the resource dictionary. These types must be
instantiable. They can’t be abstract classes, for example. These types must also have a public parameterless
constructor. Each item requires a dictionary key specified with the x:Key attribute. For example:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.SharedResourcesPage"
Title="Shared Resources Page">
<ContentPage.Resources>
<ResourceDictionary>
<LayoutOptions x:Key="horzOptions"
Alignment="Center" />
<LayoutOptions x:Key="vertOptions"
Alignment="Center"
Expands="True" />
</ResourceDictionary>
</ContentPage.Resources>
...
</ContentPage>
These two items are values of the structure type LayoutOptions , and each has a unique key and one or two
properties set. In code and markup, it’s much more common to use the static fields of LayoutOptions , but here
it’s more convenient to set the properties.
Now it’s necessary to set the HorizontalOptions and VerticalOptions properties of these buttons to these
resources, and that’s done with the StaticResource XAML markup extension:
The StaticResource markup extension is always delimited with curly braces, and includes the dictionary key.
The name StaticResource distinguishes it from DynamicResource , which Xamarin.Forms also supports.
DynamicResource is for dictionary keys associated with values that might change during runtime, while
StaticResource accesses elements from the dictionary just once when the elements on the page are constructed.
For the BorderWidth property, it’s necessary to store a double in the dictionary. XAML conveniently defines tags
for common data types like x:Double and x:Int32 :
<ContentPage.Resources>
<ResourceDictionary>
<LayoutOptions x:Key="horzOptions"
Alignment="Center" />
<LayoutOptions x:Key="vertOptions"
Alignment="Center"
Expands="True" />
<x:Double x:Key="borderWidth">
3
</x:Double>
</ResourceDictionary>
</ContentPage.Resources>
You don’t need to put it on three lines. This dictionary entry for this rotation angle only takes up one line:
<ContentPage.Resources>
<ResourceDictionary>
<LayoutOptions x:Key="horzOptions"
Alignment="Center" />
<LayoutOptions x:Key="vertOptions"
Alignment="Center"
Expands="True" />
<x:Double x:Key="borderWidth">
3
</x:Double>
<x:Double x:Key="rotationAngle">-15</x:Double>
</ResourceDictionary>
</ContentPage.Resources>
Those two resources can be referenced in the same way as the LayoutOptions values:
For resources of type Color , you can use the same string representations that you use when directly assigning
attributes of these types. The type converters are invoked when the resource is created. Here's a resource of type
Color :
<Color x:Key="textColor">Red</Color>
Often, programs set a FontSize property to a member of the NamedSize enumeration such as Large . The
FontSizeConverter class works behind the scenes to convert it into a platform -dependent value using the
Device.GetNamedSized method. However, when defining a font-size resource, it makes more sense to use a
numeric value, shown here as an x:Double type:
<x:Double x:Key="fontSize">24</x:Double>
Now all the properties except Text are defined by resource settings:
It's also possible to use OnPlatform within the resource dictionary to define different values for the platforms.
Here’s how an OnPlatform object can be part of the resource dictionary for different text colors:
<OnPlatform x:Key="textColor"
x:TypeArguments="Color">
<On Platform="iOS" Value="Red" />
<On Platform="Android" Value="Aqua" />
<On Platform="UWP" Value="#80FF80" />
</OnPlatform>
Notice that gets both an x:Key attribute because it’s an object in the dictionary and an
OnPlatform
x:TypeArguments attribute because it’s a generic class. The iOS , Android , and UWP attributes are converted to
Color values when the object is initialized.
Here’s the final complete XAML file with three buttons accessing six shared values:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.SharedResourcesPage"
Title="Shared Resources Page">
<ContentPage.Resources>
<ResourceDictionary>
<LayoutOptions x:Key="horzOptions"
Alignment="Center" />
<LayoutOptions x:Key="vertOptions"
Alignment="Center"
Expands="True" />
<x:Double x:Key="borderWidth">3</x:Double>
<x:Double x:Key="rotationAngle">-15</x:Double>
<OnPlatform x:Key="textColor"
x:TypeArguments="Color">
<On Platform="iOS" Value="Red" />
<On Platform="Android" Value="Aqua" />
<On Platform="UWP" Value="#80FF80" />
</OnPlatform>
<x:String x:Key="fontSize">Large</x:String>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Button Text="Do this!"
HorizontalOptions="{StaticResource horzOptions}"
VerticalOptions="{StaticResource vertOptions}"
BorderWidth="{StaticResource borderWidth}"
Rotation="{StaticResource rotationAngle}"
TextColor="{StaticResource textColor}"
FontSize="{StaticResource fontSize}" />
</StackLayout>
</ContentPage>
The screenshots verify the consistent styling, and the platform-dependent styling:
Although it is most common to define the Resources collection at the top of the page, keep in mind that the
Resources property is defined by VisualElement , and you can have Resources collections on other elements on
the page. For example, try adding one to the StackLayout in this example:
<StackLayout>
<StackLayout.Resources>
<ResourceDictionary>
<Color x:Key="textColor">Blue</Color>
</ResourceDictionary>
</StackLayout.Resources>
...
</StackLayout>
You’ll discover that the text color of the buttons is now blue. Basically, whenever the XAML parser encounters a
StaticResource markup extension, it searches up the visual tree and uses the first ResourceDictionary it
encounters containing that key.
One of the most common types of objects stored in resource dictionaries is the Xamarin.Forms Style , which
defines a collection of property settings. Styles are discussed in the article Styles.
Sometimes developers new to XAML wonder if they can put a visual element such as Label or Button in a
ResourceDictionary . While it’s surely possible, it doesn’t make much sense. The purpose of the
ResourceDictionary is to share objects. A visual element cannot be shared. The same instance cannot appear
twice on a single page.
So far, this is not very impressive. But the x:Static markup extension can also reference static fields or
properties from your own code. For example, here’s an AppConstants class that contains some static fields that
you might want to use on multiple pages throughout an application:
using System;
using Xamarin.Forms;
namespace XamlSamples
{
static class AppConstants
{
public static readonly Thickness PagePadding;
static AppConstants()
{
switch (Device.RuntimePlatform)
{
case Device.iOS:
PagePadding = new Thickness(5, 20, 5, 0);
TitleFont = Font.SystemFontOfSize(35, FontAttributes.Bold);
break;
case Device.Android:
PagePadding = new Thickness(5, 0, 5, 0);
TitleFont = Font.SystemFontOfSize(40, FontAttributes.Bold);
break;
case Device.UWP:
PagePadding = new Thickness(5, 0, 5, 0);
TitleFont = Font.SystemFontOfSize(50, FontAttributes.Bold);
break;
}
}
}
}
To reference the static fields of this class in the XAML file, you’ll need some way to indicate within the XAML file
where this file is located. You do this with an XML namespace declaration.
Recall that the XAML files created as part of the standard Xamarin.Forms XAML template contain two XML
namespace declarations: one for accessing Xamarin.Forms classes and another for referencing tags and
attributes intrinsic to XAML:
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
You’ll need additional XML namespace declarations to access other classes. Each additional XML namespace
declaration defines a new prefix. To access classes local to the shared application .NET Standard library, such as
AppConstants , XAML programmers often use the prefix local . The namespace declaration must indicate the
CLR (Common Language Runtime) namespace name, also known as the .NET namespace name, which is the
name that appears in a C# namespace definition or in a using directive:
xmlns:local="clr-namespace:XamlSamples"
You can also define XML namespace declarations for .NET namespaces in any assembly that the .NET Standard
library references. For example, here’s a sys prefix for the standard .NET System namespace, which is in the
mscorlib assembly, which once stood for "Microsoft Common Object Runtime Library," but now means
"Multilanguage Standard Common Object Runtime Library." Because this is another assembly, you must also
specify the assembly name, in this case mscorlib:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Notice that the keyword clr-namespace is followed by a colon and then the .NET namespace name, followed by
a semicolon, the keyword assembly , an equal sign, and the assembly name.
Yes, a colon follows clr-namespace but equal sign follows assembly . The syntax was defined in this way
deliberately: Most XML namespace declarations reference a URI that begins a URI scheme name such as http ,
which is always followed by a colon. The clr-namespace part of this string is intended to mimic that convention.
Both these namespace declarations are included in the StaticConstantsPage sample. Notice that the BoxView
dimensions are set to Math.PI and Math.E , but scaled by a factor of 100:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
x:Class="XamlSamples.StaticConstantsPage"
Title="Static Constants Page"
Padding="{x:Static local:AppConstants.PagePadding}">
<StackLayout>
<Label Text="Hello, XAML!"
TextColor="{x:Static local:AppConstants.BackgroundColor}"
BackgroundColor="{x:Static local:AppConstants.ForegroundColor}"
Font="{x:Static local:AppConstants.TitleFont}"
HorizontalOptions="Center" />
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.RelativeLayoutPage"
Title="RelativeLayout Page">
<RelativeLayout>
Perhaps the most important lesson you should take from this sample is the syntax of the markup extension: No
quotation marks must appear within the curly braces of a markup extension. When typing the markup extension
in a XAML file, it is natural to want to enclose the values of the properties in quotation marks. Resist the
temptation!
Here’s the program running:
Summary
The XAML markup extensions shown here provide important support for XAML files. But perhaps the most
valuable XAML markup extension is Binding , which is covered in the next part of this series, Part 4. Data
Binding Basics.
Related Links
XamlSamples
Part 1. Getting Started with XAML
Part 2. Essential XAML Syntax
Part 4. Data Binding Basics
Part 5. From Data Binding to MVVM
Part 4. Data Binding Basics
6/8/2018 • 11 minutes to read • Edit Online
Data bindings allow properties of two objects to be linked so that a change in one causes a change in the other.
This is a very valuable tool, and while data bindings can be defined entirely in code, XAML provides shortcuts
and convenience. Consequently, one of the most important markup extensions in Xamarin.Forms is Binding.
Data Bindings
Data bindings connect properties of two objects, called the source and the target. In code, two steps are
required: The BindingContext property of the target object must be set to the source object, and the
SetBinding method (often used in conjunction with the Binding class) must be called on the target object to
bind a property of that object to a property of the source object.
The target property must be a bindable property, which means that the target object must derive from
BindableObject . The online Xamarin.Forms documentation indicates which properties are bindable properties.
A property of Label such as Text is associated with the bindable property TextProperty .
In markup, you must also perform the same two steps that are required in code, except that the Binding
markup extension takes the place of the SetBinding call and the Binding class.
However, when you define data bindings in XAML, there are multiple ways to set the BindingContext of the
target object. Sometimes it’s set from the code-behind file, sometimes using a StaticResource or x:Static
markup extension, and sometimes as the content of BindingContext property-element tags.
Bindings are used most often to connect the visuals of a program with an underlying data model, usually in a
realization of the MVVM (Model-View -ViewModel) application architecture, as discussed in Part 5. From Data
Bindings to MVVM, but other scenarios are possible.
View-to-View Bindings
You can define data bindings to link properties of two views on the same page. In this case, you set the
BindingContext of the target object using the x:Reference markup extension.
Here’s a XAML file that contains a Slider and two Label views, one of which is rotated by the Slider value
and another which displays the Slider value:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.SliderBindingsPage"
Title="Slider Bindings Page">
<StackLayout>
<Label Text="ROTATION"
BindingContext="{x:Reference Name=slider}"
Rotation="{Binding Path=Value}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Slider x:Name="slider"
Maximum="360"
VerticalOptions="CenterAndExpand" />
The Slider contains an x:Name attribute that is referenced by the two Label views using the x:Reference
markup extension.
The x:Reference binding extension defines a property named Name to set to the name of the referenced
element, in this case slider . However, the ReferenceExtension class that defines the x:Reference markup
extension also defines a ContentProperty attribute for Name , which means that it isn’t explicitly required. Just
for variety, the first x:Reference includes “Name=” but the second does not:
BindingContext="{x:Reference Name=slider}"
…
BindingContext="{x:Reference slider}"
The Binding markup extension itself can have several properties, just like the BindingBase and Binding class.
The ContentProperty for Binding is Path , but the “Path=” part of the markup extension can be omitted if the
path is the first item in the Binding markup extension. The first example has “Path=” but the second example
omits it:
Rotation="{Binding Path=Value}"
…
Text="{Binding Value, StringFormat='The angle is {0:F0} degrees'}"
The properties can all be on one line or separated into multiple lines:
Text="{Binding Value,
StringFormat='The angle is {0:F0} degrees'}"
Do whatever is convenient.
Notice the StringFormat property in the second Binding markup extension. In Xamarin.Forms, bindings do not
perform any implicit type conversions, and if you need to display a non-string object as a string you must
provide a type converter or use StringFormat . Behind the scenes, the static String.Format method is used to
implement StringFormat . That’s potentially a problem, because .NET formatting specifications involve curly
braces, which are also used to delimit markup extensions. This creates a risk of confusing the XAML parser. To
avoid that, put the entire formatting string in single quotation marks:
The solution to this and other problems involves the Mode property, which is set to a member of the
BindingMode enumeration:
Default
OneWay — values are transferred from the source to the target
OneWayToSource — values are transferred from the target to the source
TwoWay — values are transferred both ways between source and target
The following program demonstrates one common use of the OneWayToSource and TwoWay binding modes.
Four Slider views are intended to control the Scale , Rotate , RotateX , and RotateY properties of a Label .
At first, it seems as if these four properties of the Label should be data-binding targets because each is being
set by a Slider . However, the BindingContext of Label can be only one object, and there are four different
sliders.
For that reason, all the bindings are set in seemingly backwards ways: The BindingContext of each of the four
sliders is set to the Label , and the bindings are set on the Value properties of the sliders. By using the
OneWayToSource and TwoWay modes, these Value properties can set the source properties, which are the
Scale , Rotate , RotateX , and RotateY properties of the Label :
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.SliderTransformsPage"
Padding="5"
Title="Slider Transforms Page">
Title="Slider Transforms Page">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
The bindings on three of the Slider views are OneWayToSource , meaning that the Slider value causes a
change in the property of its BindingContext , which is the Label named label . These three Slider views
cause changes to the Rotate , RotateX , and RotateY properties of the Label .
However, the binding for the Scale property is TwoWay . This is because the Scale property has a default value
of 1, and using a TwoWay binding causes the Slider initial value to be set at 1 rather than 0. If that binding
were OneWayToSource , the Scale property would initially be set to 0 from the Slider default value. The Label
would not be visible, and that might cause some confusion to the user.
</ContentPage>
The resultant display establishes that the items are truly of type XamlSamples.NamedColor :
It’s not much information, but the ListView is scrollable and selectable.
To define a template for the items, you’ll want to break out the ItemTemplate property as a property element,
and set it to a DataTemplate , which then references a ViewCell . To the View property of the ViewCell you can
define a layout of one or more views to display each item. Here’s a simple example:
The Label element is set to the View property of the ViewCell . (The ViewCell.View tags are not needed
because the View property is the content property of ViewCell .) This markup displays the FriendlyName
property of each NamedColor object:
Much better. Now all that’s needed is to spruce up the item template with more information and the actual color.
To support this template, some values and objects have been defined in the page’s resource dictionary:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples"
x:Class="XamlSamples.ListViewDemoPage"
Title="ListView Demo Page">
<ContentPage.Resources>
<ResourceDictionary>
<OnPlatform x:Key="boxSize"
x:TypeArguments="x:Double">
<On Platform="iOS, Android, UWP" Value="50" />
</OnPlatform>
<OnPlatform x:Key="rowHeight"
x:TypeArguments="x:Int32">
<On Platform="iOS, Android, UWP" Value="60" />
</OnPlatform>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout Orientation="Horizontal"
<StackLayout Orientation="Horizontal"
Spacing="0">
<Label Text="{Binding Color.R,
Converter={StaticResource intConverter},
ConverterParameter=255,
StringFormat='R={0:X2}'}" />
Notice the use of OnPlatform to define the size of a BoxView and the height of the ListView rows. Although
the values for all three platforms are the same, the markup could easily be adapted for other values to fine-tune
the display.
namespace XamlSamples
{
class DoubleToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
double multiplier;
The ConvertBack method does not play a role in this program because the bindings are only one way from
source to target.
A binding references a binding converter with the Converter property. A binding converter can also accept a
parameter specified with the ConverterParameter property. For some versatility, this is how the multiplier is
specified. The binding converter checks the converter parameter for a valid double value.
The converter is instantiated in the resource dictionary so it can be shared among multiple bindings:
Three data bindings reference this single instance. Notice that the Binding markup extension contains an
embedded StaticResource markup extension:
Summary
Data bindings provide a powerful mechanism for linking properties between two objects within a page, or
between visual objects and underlying data. But when the application begins working with data sources, a
popular application architectural pattern begins to emerge as a useful paradigm. This is covered in Part 5. From
Data Bindings to MVVM.
Related Links
XamlSamples
Part 1. Getting Started with XAML (sample)
Part 2. Essential XAML Syntax (sample)
Part 3. XAML Markup Extensions (sample)
Part 5. From Data Binding to MVVM (sample)
Part 5. From Data Bindings to MVVM
6/20/2018 • 13 minutes to read • Edit Online
The Model-View -ViewModel (MVVM ) architectural pattern was invented with XAML in mind. The pattern
enforces a separation between three software layers — the XAML user interface, called the View; the underlying
data, called the Model; and an intermediary between the View and the Model, called the ViewModel. The View
and the ViewModel are often connected through data bindings defined in the XAML file. The BindingContext for
the View is usually an instance of the ViewModel.
A Simple ViewModel
As an introduction to ViewModels, let’s first look at a program without one. Earlier you saw how to define a new
XML namespace declaration to allow a XAML file to reference classes in other assemblies. Here’s a program that
defines an XML namespace declaration for the System namespace:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
The program can use x:Static to obtain the current date and time from the static DateTime.Now property and
set that DateTime value to the BindingContext on a StackLayout :
BindingContext is a very special property: When you set the BindingContext on an element, it is inherited by all
the children of that element. This means that all the children of the StackLayout have this same BindingContext ,
and they can contain simple bindings to properties of that object.
In the One-Shot DateTime program, two of the children contain bindings to properties of that DateTime value,
but two other children contain bindings that seem to be missing a binding path. This means that the DateTime
value itself is used for the StringFormat :
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
x:Class="XamlSamples.OneShotDateTimePage"
Title="One-Shot DateTime Page">
</StackLayout>
</ContentPage>
Of course, the big problem is that the date and time are set once when the page is first built, and never change:
A XAML file can display a clock that always shows the current time, but it needs some code to help out. When
thinking in terms of MVVM, the Model and ViewModel are classes written entirely in code. The View is often a
XAML file that references properties defined in the ViewModel through data bindings.
A proper Model is ignorant of the ViewModel, and a proper ViewModel is ignorant of the View. However, very
often a programmer tailors the data types exposed by the ViewModel to the data types associated with
particular user interfaces. For example, if a Model accesses a database that contains 8-bit character ASCII
strings, the ViewModel would need to convert between those strings to Unicode strings to accommodate the
exclusive use of Unicode in the user interface.
In simple examples of MVVM (such as those shown here), often there is no Model at all, and the pattern involves
just a View and ViewModel linked with data bindings.
Here’s a ViewModel for a clock with just a single property named DateTime , but which updates that DateTime
property every second:
using System;
using System.ComponentModel;
using Xamarin.Forms;
namespace XamlSamples
{
class ClockViewModel : INotifyPropertyChanged
{
DateTime dateTime;
public ClockViewModel()
{
this.DateTime = DateTime.Now;
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
this.DateTime = DateTime.Now;
return true;
});
}
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("DateTime"));
}
}
}
get
{
return dateTime;
}
}
}
}
ViewModels generally implement the INotifyPropertyChanged interface, which means that the class fires a
PropertyChanged event whenever one of its properties changes. The data binding mechanism in Xamarin.Forms
attaches a handler to this PropertyChanged event so it can be notified when a property changes and keep the
target updated with the new value.
A clock based on this ViewModel can be as simple as this:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples;assembly=XamlSamples"
x:Class="XamlSamples.ClockPage"
Title="Clock Page">
Notice how the ClockViewModel is set to the BindingContext of the Label using property element tags.
Alternatively, you can instantiate the ClockViewModel in a Resources collection and set it to the BindingContext
via a StaticResource markup extension. Or, the code-behind file can instantiate the ViewModel.
The Binding markup extension on the Text property of the Label formats the DateTime property. Here’s the
display:
It’s also possible to access individual properties of the DateTime property of the ViewModel by separating the
properties with periods:
Interactive MVVM
MVVM is quite often used with two-way data bindings for an interactive view based on an underlying data
model.
Here’s a class named HslViewModel that converts a Color value into Hue , Saturation , and Luminosity values,
and vice versa:
using System;
using System.ComponentModel;
using Xamarin.Forms;
namespace XamlSamples
{
public class HslViewModel : INotifyPropertyChanged
{
double hue, saturation, luminosity;
Color color;
void SetNewColor()
{
Color = Color.FromHsla(Hue, Saturation, Luminosity);
}
Changes to the Hue , Saturation , and Luminosity properties cause the Color property to change, and changes
to Color causes the other three properties to change. This might seem like an infinite loop, except that the class
doesn't invoke the PropertyChanged event unless the property has actually changed. This puts an end to the
otherwise uncontrollable feedback loop.
The following XAML file contains a BoxView whose Color property is bound to the Color property of the
ViewModel, and three Slider and three Label views bound to the Hue , Saturation , and Luminosity
properties:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples;assembly=XamlSamples"
x:Class="XamlSamples.HslColorScrollPage"
Title="HSL Color Scroll Page">
<ContentPage.BindingContext>
<local:HslViewModel Color="Aqua" />
</ContentPage.BindingContext>
The binding on each Label is the default OneWay . It only needs to display the value. But the binding on each
Slider is . This allows the Slider to be initialized from the ViewModel. Notice that the Color property
TwoWay
is set to Aqua when the ViewModel is instantiated. But a change in the Slider also needs to set a new value for
the property in the ViewModel, which then calculates a new color.
With the exception of the SearchBar and ListView element, these elements define two properties:
Command of type System.Windows.Input.ICommand
CommandParameter of type Object
The ViewModel can define properties of type ICommand . You can then bind these properties to the Command
property of each Button or other element, or perhaps a custom view that implements this interface. You can
optionally set the CommandParameter property to identify individual Button objects (or other elements) that are
bound to this ViewModel property. Internally, the Button calls the Execute method whenever the user taps the
Button , passing to the Execute method its CommandParameter .
The CanExecute method and CanExecuteChanged event are used for cases where a Button tap might be currently
invalid, in which case the Button should disable itself. The Button calls CanExecute when the Command property
is first set and whenever the CanExecuteChanged event is fired. If CanExecute returns false , the Button disables
itself and doesn’t generate Execute calls.
For help in adding commanding to your ViewModels, Xamarin.Forms defines two classes that implement
ICommand : Command and Command<T> where T is the type of the arguments to Execute and CanExecute . These
two classes define several constructors plus a ChangeCanExecute method that the ViewModel can call to force the
Command object to fire the CanExecuteChanged event.
Here is a ViewModel for a simple keypad that is intended for entering telephone numbers. Notice that the
Execute and CanExecute method are defined as lambda functions right in the constructor:
using System;
using System.ComponentModel;
using System.Windows.Input;
using Xamarin.Forms;
namespace XamlSamples
{
class KeypadViewModel : INotifyPropertyChanged
{
string inputString = "";
string displayText = "";
char[] specialChars = { '*', '#' };
// Constructor
public KeypadViewModel()
{
AddCharCommand = new Command<string>((key) =>
{
// Add the key to the input string.
InputString += key;
});
// Public properties
public string InputString
{
protected set
{
if (inputString != value)
{
{
inputString = value;
OnPropertyChanged("InputString");
DisplayText = FormatText(inputString);
// ICommand implementations
public ICommand AddCharCommand { protected set; get; }
This ViewModel assumes that the AddCharCommand property is bound to the Command property of several buttons
(or anything else that has a command interface), each of which is identified by the CommandParameter . These
buttons add characters to an InputString property, which is then formatted as a phone number for the
DisplayText property.
There is also a second property of type ICommand named DeleteCharCommand . This is bound to a back-spacing
button, but the button should be disabled if there are no characters to delete.
The following keypad is not as visually sophisticated as it could be. Instead, the markup has been reduced to a
minimum to demonstrate more clearly the use of the command interface:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples;assembly=XamlSamples"
x:Class="XamlSamples.KeypadPage"
Title="Keypad Page">
<Grid HorizontalOptions="Center"
VerticalOptions="Center">
<Grid.BindingContext>
<local:KeypadViewModel />
</Grid.BindingContext>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<Frame Grid.Column="0"
OutlineColor="Accent">
<Label Text="{Binding DisplayText}" />
</Frame>
<Button Text="⇦"
Command="{Binding DeleteCharCommand}"
Grid.Column="1"
BorderWidth="0" />
</Grid>
<Button Text="1"
Command="{Binding AddCharCommand}"
CommandParameter="1"
Grid.Row="1" Grid.Column="0" />
<Button Text="2"
Command="{Binding AddCharCommand}"
CommandParameter="2"
Grid.Row="1" Grid.Column="1" />
<Button Text="3"
Command="{Binding AddCharCommand}"
CommandParameter="3"
Grid.Row="1" Grid.Column="2" />
<Button Text="4"
Command="{Binding AddCharCommand}"
CommandParameter="4"
Grid.Row="2" Grid.Column="0" />
<Button Text="5"
Command="{Binding AddCharCommand}"
CommandParameter="5"
Grid.Row="2" Grid.Column="1" />
<Button Text="6"
Command="{Binding AddCharCommand}"
CommandParameter="6"
Grid.Row="2" Grid.Column="2" />
<Button Text="7"
Command="{Binding AddCharCommand}"
CommandParameter="7"
Grid.Row="3" Grid.Column="0" />
<Button Text="8"
Command="{Binding AddCharCommand}"
CommandParameter="8"
Grid.Row="3" Grid.Column="1" />
<Button Text="9"
Command="{Binding AddCharCommand}"
CommandParameter="9"
Grid.Row="3" Grid.Column="2" />
<Button Text="*"
Command="{Binding AddCharCommand}"
CommandParameter="*"
Grid.Row="4" Grid.Column="0" />
<Button Text="0"
Command="{Binding AddCharCommand}"
CommandParameter="0"
Grid.Row="4" Grid.Column="1" />
<Button Text="#"
Command="{Binding AddCharCommand}"
CommandParameter="#"
Grid.Row="4" Grid.Column="2" />
</Grid>
</ContentPage>
The Command property of the first Button that appears in this markup is bound to the DeleteCharCommand ; the
rest are bound to the AddCharCommand with a CommandParameter that is the same as the character that appears on
the Button face. Here’s the program in action:
Invoking Asynchronous Methods
Commands can also invoke asynchronous methods. This is achieved by using the async and await keywords
when specifying the Execute method:
This indicates that the DownloadAsync method is a Task and should be awaited:
void Download ()
{
...
}
The XAML file for MainPage defines a ListBox whose ItemsSource property is set to that All property and
which contains a TextCell for displaying the Title and Description properties of each page:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples"
x:Class="XamlSamples.MainPage"
Padding="5, 0"
Title="XAML Samples">
The handler in the code-behind file is triggered when the user selects an item. The handler sets the SelectedItem
property of the ListBox back to null and then instantiates the selected page and navigates to it:
if (args.SelectedItem != null)
{
PageDataViewModel pageData = args.SelectedItem as PageDataViewModel;
Page page = (Page)Activator.CreateInstance(pageData.Type);
await Navigation.PushAsync(page);
}
}
Video
Xamarin Evolve 2016: MVVM Made Simple with Xamarin.Forms and Prism
Summary
XAML is a powerful tool for defining user interfaces in Xamarin.Forms applications, particularly when data-
binding and MVVM are used. The result is a clean, elegant, and potentially toolable representation of a user
interface with all the background support in code.
Related Links
XamlSamples
Part 1. Getting Started with XAML
Part 2. Essential XAML Syntax
Part 3. XAML Markup Extensions
Part 4. Data Binding Basics
XAML Compilation in Xamarin.Forms
7/12/2018 • 2 minutes to read • Edit Online
XAML can be optionally compiled directly into intermediate language (IL ) with the XAML compiler (XAMLC ).
XAMLC offers a number of a benefits:
It performs compile-time checking of XAML, notifying the user of any errors.
It removes some of the load and instantiation time for XAML elements.
It helps to reduce the file size of the final assembly by no longer including .xaml files.
XAMLC is disabled by default to ensure backwards compatibility. It can be enabled at both the assembly and class
level by adding the XamlCompilation attribute.
The following code example demonstrates enabling XAMLC at the assembly level:
using Xamarin.Forms.Xaml;
...
[assembly: XamlCompilation (XamlCompilationOptions.Compile)]
namespace PhotoApp
{
...
}
In this example, compile-time checking of all the XAML contained within the assembly will be performed, with
XAML errors being reported at compile-time rather than run-time. Therefore, the assembly prefix to the
XamlCompilation attribute specifies that the attribute applies to the entire assembly.
The following code example demonstrates enabling XAMLC at the class level:
using Xamarin.Forms.Xaml;
...
[XamlCompilation (XamlCompilationOptions.Compile)]
public class HomePage : ContentPage
{
...
}
In this example, compile-time checking of the XAML for the HomePage class will be performed and errors reported
as part of the compilation process.
NOTE
The XamlCompilation attribute and the XamlCompilationOptions enumeration reside in the Xamarin.Forms.Xaml
namespace, which must be imported to use them.
Related Links
XamlCompilation
XamlCompilationOptions
Xamarin Live Reload
6/27/2018 • 7 minutes to read • Edit Online
Xamarin Live Reload enables you to make changes to your XAML and see them reflected live, without
requiring another compile and deploy. Any changes made to your XAML will be redeployed on save and
reflected on your deploy target.
Because your app is compiled when using Live Reload, it works with all libraries and third-party controls. Live
Reload works on all platforms Xamarin.Forms supports, including Android, iOS, and UWP, and works on all valid
deployment targets, including simulators, emulators, and physical devices.
Requirements
Visual Studio 2017 version 15.7 or above or above with the Mobile development with .NET workload.
Xamarin.Forms 3.0.0 or above or above.
Getting Started
1. Install Xamarin Live Reload from the Visual Studio Marketplace
Xamarin Live Reload is distributed via the Visual Studio Marketplace. To install the extension, visit the Xamarin Live
Reload page on the Visual Studio Marketplace website and click Download.
Open the .vsix that is downloaded, and click Install.
Alternatively, you can search for it in the Online tab in the Extensions and Updates dialog inside Visual Studio.
2. Configure your app to use Live Reload
Adding Live Reload to existing mobile apps can be done in three steps:
1. Ensure all projects are updated to use Xamarin.Forms 3.0.0 or above or above.
2. Add the Xamarin.LiveReload NuGet package:
a. .NET Standard – Install the Xamarin.LiveReload NuGet into your .NET Standard 2.0 library. This does
not need to be installed in your platform projects. Ensure that the Package source is set to All.
b. Shared Projects – Install the Xamarin.LiveReload NuGet into all platform projects (such as Android,
iOS, UWP, etc.). Ensure that the Package source is set to All.
3. Add LiveReload.Init(); to the constructor in the Application class, as shown in the following code snippet:
InitializeComponent();
MainPage = new MainPage();
}
}
Live Reload works with changes to any XAML file. Changes to C# or adding/removing NuGet packages requires a
new build and deploy to take effect.
Limitations
Only reloading of XAML is supported.
UI state may not be maintained between redeploys, unless using MVVM.
Known Issues
Only supported in Visual Studio.
Linking must be set to Don't Link or Link Framework SDKs Only
Reloading app-wide resources (i.e. App.xaml or shared resource dictionaries), app navigation is reset. This will
be fixed in the next preview release.
Editing XAML while debugging UWP may cause a runtime crash. Workaround: Use Start without Debugging
(Ctrl + F5) instead of Start Debugging (F5).
Troubleshooting
Error codes
XLR001: The current project references 'Xamarin.LiveReload' NuGet package version ' [VERSION ]' but the
Xamarin Live Reload extension requires version ' [VERSION ]'.
In order to allow rapid iteration and evolution of the Live Reload feature, the nuget package and the Visual
Studio extension must match exactly. Update your nuget package to the same version of the extension you
have installed.
XLR002: Live Reload requires at least the 'MqttHostname' property when building from the command line.
Alternatively, set 'EnableLiveReload' to 'false' to disable the feature.
The properties required by Live Reload are not available when building from the command line (or in
continuous integration), and must therefore be provided explicitly.
XLR003: Live Reload nuget package requires installing the Xamarin Live Reload Visual Studio extension.
Attempted to build a project that references the Live Reload nuget package but the Visual Extension is not
installed.
Exception while loading assemblies: System.IO.FileNotFoundException: Could not load assembly
'Xamarin.Live.Reload, Version=0.3.27.0, Culture=neutral, PublicKeyToken='.
The host project should be using PackageReference instead of packages.config
Now you can use that IP to connect to your own MQTT server.
XAML Previewer for Xamarin.Forms
6/8/2018 • 2 minutes to read • Edit Online
Requirements
Projects require the latest Xamarin.Forms NuGet package for the XAML Previewer to work. Previewing Android
apps requires JDK 1.8 x64.
There is more information in the release notes.
Getting Started
Visual Studio
Visual Studio for Mac
Use the View > Other Windows > Xamarin.Forms Previewer menu in Visual Studio to open the preview
window. Use the Window > New Vertical Tab Group menu to position it side-by-side.
if (DesignMode.IsDesignModeEnabled)
{
// Previewer only code
}
Troubleshooting
Check the issues below, and the Xamarin Forums, if you encounter problems.
XAML Preview isn't showing
Check the following:
Project should be built (compiled) before attempting to preview XAML files.
The Designer Agent must be set-up the first time you preview a XAML file - a progress indicator will appear in
the Previewer, along with progress messages, until this is ready.
Try closing and re-opening the XAML file.
Invalid XAML: The Android project needs to built before preview can be created
The XAML Previewer requires that the project be built before rendering a page. If the error below appears at the
top of the preview pane, re-build the application and try again.
XAML Namespaces in Xamarin.Forms
7/12/2018 • 3 minutes to read • Edit Online
XAML uses the xmlns XML attribute for namespace declarations. This article introduces the XAML namespace
syntax, and demonstrates how to declare a XAML namespace to access a type.
Overview
There are two XAML namespace declarations that are always within the root element of a XAML file. The first
defines the default namespace, as shown in the following XAML code example:
xmlns="http://xamarin.com/schemas/2014/forms"
The default namespace specifies that elements defined within the XAML file with no prefix refer to Xamarin.Forms
classes, such as ContentPage .
The second namespace declaration uses the x prefix, as shown in the following XAML code example:
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
XAML uses prefixes to declare non-default namespaces, with the prefix being used when referencing types within
the namespace. The x namespace declaration specifies that elements defined within the XAML with a prefix of
x are used for elements and attributes that are intrinsic to XAML (specifically the 2009 XAML specification).
CONSTRUCT DESCRIPTION
x:Class Specifies the namespace and class name for a class defined in
XAML. The class name must match the class name of the
code-behind file. Note that this construct can only appear in
the root element of a XAML file.
x:FieldModifier Specifies the access level for generated fields for named XAML
elements.
For more information about the x:FieldModifier attribute, see Field Modifiers. For more information about the
x:Arguments , x:FactoryMethod , and x:TypeArguments attributes, see Passing Arguments in XAML.
In XAML, namespace declarations inherit from parent element to child element. Therefore, when defining a
namespace in the root element of a XAML file, all elements within that file inherit the namespace declaration.
The local prefix is a convention used to indicate that the types within the namespace are local to the application.
Alternatively, if the types are in a different assembly, the assembly name should also be defined in the namespace
declaration, as demonstrated in the following XAML code example:
The namespace prefix is then specified when declaring an instance of a type from an imported namespace, as
demonstrated in the following XAML code example:
<ListView ...>
<ListView.Behaviors>
<behaviors:EventToCommandBehavior EventName="ItemSelected" ... />
</ListView.Behaviors>
</ListView>
Summary
This article introduced the XAML namespace syntax, and demonstrated how to declare a XAML namespace to
access a type. XAML uses the xmlns XML attribute for namespace declarations, and types can be referenced in
XAML by declaring a XAML namespace with a prefix.
Related Links
Passing Arguments in XAML
XAML Markup Extensions
7/12/2018 • 2 minutes to read • Edit Online
XAML markup extensions help extend the power and flexibility of XAML by allowing element attributes to be set
from sources other than literal text strings.
For example, normally you set the Color property of BoxView like this:
In either case, the text string set to the Color attribute is converted to a Color value by the ColorTypeConverter
class.
You might prefer instead to set the Color attribute from a value stored in a resource dictionary, or from the value
of a static property of a class that you've created, or from a property of type Color of another element on the
page, or constructed from separate hue, saturation, and luminosity values.
All these options are possible using XAML markup extensions. But don't let the phrase "markup extensions" scare
you: XAML markup extensions are not extensions to XML. Even with XAML markup extensions, XAML is always
legal XML.
A markup extension is really just a different way to express an attribute of an element. XAML markup extensions
are usually identifiable by an attribute setting that is enclosed in curly braces:
Any attribute setting in curly braces is always a XAML markup extension. However, as you'll see, XAML markup
extensions can also be referenced without the use of curly braces.
This article is divided in two parts:
Related Links
Markup Extensions (sample)
XAML markup extensions chapter from Xamarin.Forms book
Resource Dictionaries
Dynamic Styles
Data Binding
Consuming XAML Markup Extensions
7/12/2018 • 10 minutes to read • Edit Online
XAML markup extensions help enhance the power and flexibility of XAML by allowing element attributes to be set
from a variety of sources. Several XAML markup extensions are part of the XAML 2009 specification. These
appear in XAML files with the customary x namespace prefix, and are commonly referred to with this prefix.
These are described in the sections below:
x:Static – reference static properties, fields, or enumeration members.
x:Reference – reference named elements on the page.
x:Type – set an attribute to a System.Type object.
x:Array – construct an array of objects of a particular type.
x:Null – set an attribute to a null value.
Three other XAML markup extensions have historically been supported by other XAML implementations, and are
also supported by Xamarin.Forms. These are described more fully in other articles:
StaticResource – reference objects from a resource dictionary, as described in the article Resource
Dictionaries.
DynamicResource – respond to changes in objects in a resource dictionary, as described in the article Dynamic
Styles.
Binding– establish a link between properties of two objects, as described in the article Data Binding.
TemplateBinding – performs data binding from a control template, as discussed in the article [ Binding from a
Control Template]/guides/xamarin-forms/application-fundamentals/templates/control-templates/template-
binding/)
The RelativeLayout layout makes use of the custom markup extension ConstraintExpression . This markup
extension is described in the article RelativeLayout.
The x:Static Demo page demonstrates several ways to use the x:Static markup extension. The most verbose
approach instantiates the StaticExtension class between Label.FontSize property-element tags:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.StaticDemoPage"
Title="x:Static Demo">
<StackLayout Margin="10, 0">
<Label Text="Label No. 1">
<Label.FontSize>
<x:StaticExtension Member="local:AppConstants.NormalFontSize" />
</Label.FontSize>
</Label>
···
</StackLayout>
</ContentPage>
The XAML parser also allows the StaticExtension class to be abbreviated as x:Static :
This can be simplified even further, but the change introduces some new syntax: It consists of putting the
StaticExtension class and the member setting in curly braces. The resulting expression is set directly to the
FontSize attribute:
Notice that there are no quotation marks within the curly braces. The Member property of StaticExtension is no
longer an XML attribute. It is instead part of the expression for the markup extension.
Just as you can abbreviate x:StaticExtension to x:Static when you use it as an object element, you can also
abbreviate it in the expression within curly braces:
The StaticExtension class has a ContentProperty attribute referencing the property Member , which marks this
property as the class's default content property. For XAML markup extensions expressed with curly braces, you can
eliminate the Member= part of the expression:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
This allows the Label font size to be set to the static field Math.PI . That results in rather small text, so the Scale
property is set to Math.E :
The final example displays the Device.RuntimePlatform value. The Environment.NewLine static property is used to
insert a new -line character between the two Span objects:
<Label HorizontalTextAlignment="Center"
FontSize="{x:Static local:AppConstants.NormalFontSize}">
<Label.FormattedText>
<FormattedString>
<Span Text="Runtime Platform: " />
<Span Text="{x:Static sys:Environment.NewLine}" />
<Span Text="{x:Static Device.RuntimePlatform}" />
</FormattedString>
</Label.FormattedText>
</Label>
The x:Reference markup extension is used exclusively with data bindings, which are described in more detail in
the article Data Binding.
The x:Reference Demo page shows two uses of x:Reference with data bindings, the first where it's used to set
the Source property of the Binding object, and the second where it's used to set the BindingContext property for
two data bindings:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.ReferenceDemoPage"
x:Name="page"
Title="x:Reference Demo">
<Slider x:Name="slider"
Maximum="360"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
Both x:Reference expressions use the abbreviated version of the ReferenceExtension class name and eliminate
the Name= part of the expression. In the first example, the x:Reference markup extension is embedded in the
Binding markup extension. Notice that the Source and StringFormat settings are separated by commas. Here's
the program running on all three platforms:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.MainPage"
Title="Markup Extensions"
Padding="10">
<TableView Intent="Menu">
<TableRoot>
<TableSection>
<TextCell Text="x:Static Demo"
Detail="Access constants or statics"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:StaticDemoPage}" />
···
</TableRoot>
</TableView>
</ContentPage>
BindingContext = this;
}
The NavigateCommand property is a Command object that implements an execute command with an argument of
type Type — the value of CommandParameter . The method uses Activator.CreateInstance to instantiate the page
and then navigates to it. The constructor concludes by setting the BindingContext of the page to itself, which
enables the Binding on Command to work. See the Data Binding article and particularly the Commanding
article for more details about this type of code.
The x:Type Demo page uses a similar technique to instantiate Xamarin.Forms elements and to add them to a
StackLayout . The XAML file initially consists of three Button elements with their Command properties set to a
Binding and the CommandParameter properties set to types of three Xamarin.Forms views:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.TypeDemoPage"
Title="x:Type Demo">
<StackLayout x:Name="stackLayout"
Padding="10, 0">
BindingContext = this;
}
The method that is executed when a Button is pressed creates a new instance of the argument, sets its
VerticalOptions property, and adds it to the StackLayout . The three Button elements then share the page with
dynamically created views:
x:Array Markup Extension
The x:Array markup extension allows you to define an array in markup. It is supported by the ArrayExtension
class, which defines two properties:
Type of type Type , which indicates the type of the elements in the array.
Items of type IList , which is a collection of the items themselves. This is the content property of
ArrayExtension .
The x:Array markup extension itself never appears in curly braces. Instead, x:Array start and end tags delimit the
list of items. Set the Type property to an x:Type markup extension.
The x:Array Demo page shows how to use x:Array to add items to a ListView by setting the ItemsSource
property to an array:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MarkupExtensions.ArrayDemoPage"
Title="x:Array Demo Page">
<ListView Margin="10">
<ListView.ItemsSource>
<x:Array Type="{x:Type Color}">
<Color>Aqua</Color>
<Color>Black</Color>
<Color>Blue</Color>
<Color>Fuchsia</Color>
<Color>Gray</Color>
<Color>Green</Color>
<Color>Lime</Color>
<Color>Maroon</Color>
<Color>Navy</Color>
<Color>Olive</Color>
<Color>Pink</Color>
<Color>Purple</Color>
<Color>Red</Color>
<Color>Silver</Color>
<Color>Teal</Color>
<Color>White</Color>
<Color>Yellow</Color>
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<BoxView Color="{Binding}"
Margin="3" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
There are several ways to specify the individual Color items in this array. You can use an x:Static markup
extension:
<x:Static Member="Color.Blue" />
Or, you can use StaticResource to retrieve a color from a resource dictionary:
Towards the end of this article, you'll see a custom XAML markup extension that also creates a new color value:
When defining arrays of common types like strings or numbers, use the tags listed in the Passing Constructor
Arguments article to delimit the values.
<ContentPage.Content>
<StackLayout Padding="10, 0">
<Label Text="Text 1" />
<Label Text="Text 2" />
Then you discover that for one of the Label elements, you want all the property settings in the implicit Style
except for the FontFamily , which you want to be the default value. You could define another Style for that
purpose but a simpler approach is simply to set the FontFamily property of the particular Label to x:Null , as
demonstrated in the center Label .
Here's the program running on the three platforms:
Notice that four of the Label elements have a serif font, but the center Label has the default sans-serif font.
Define Your Own Markup Extensions
If you've encountered a need for a XAML markup extension that isn't available in Xamarin.Forms, you can create
your own.
Related Links
Markup Extensions (sample)
XAML markup extensions chapter from Xamarin.Forms book
Resource Dictionaries
Dynamic Styles
Data Binding
Creating XAML Markup Extensions
7/12/2018 • 5 minutes to read • Edit Online
On the programmatic level, a XAML markup extension is a class that implements the IMarkupExtension or
IMarkupExtension<T> interface. You can explore the source code of the standard markup extensions described
below in the MarkupExtensions directory of the Xamarin.Forms GitHub repository.
It's also possible to define your own custom XAML markup extensions by deriving from IMarkupExtension or
IMarkupExtension<T> . Use the generic form if the markup extension obtains a value of a particular type. This is the
case with several of the Xamarin.Forms markup extensions:
TypeExtension derives from IMarkupExtension<Type>
ArrayExtension derives from IMarkupExtension<Array>
DynamicResourceExtension derives from IMarkupExtension<DynamicResource>
BindingExtension derives from IMarkupExtension<BindingBase>
ConstraintExpression derives from IMarkupExtension<Constraint>
The two IMarkupExtension interfaces define only one method each, named ProvideValue :
Since IMarkupExtension<T> derives from IMarkupExtension and includes the new keyword on ProvideValue , it
contains both ProvideValue methods.
Very often, XAML markup extensions define properties that contribute to the return value. (The obvious exception
is NullExtension , in which ProvideValue simply returns null .) The ProvideValue method has a single argument
of type IServiceProvider that will be discussed later in this article.
Because IMarkupExtension<T> derives from IMarkupExtension , the class must contain two ProvideValue methods,
one that returns Color and another that returns object , but the second method can simply call the first method.
The HSL Color Demo page shows a variety of ways that HslColorExtension can appear in a XAML file to specify
the color for a BoxView :
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.HslColorDemoPage"
Title="HSL Color Demo">
<ContentPage.Resources>
<ResourceDictionary>
<Style TargetType="BoxView">
<Setter Property="WidthRequest" Value="80" />
<Setter Property="HeightRequest" Value="80" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<BoxView>
<BoxView.Color>
<local:HslColorExtension H="0" S="1" L="0.5" A="1" />
</BoxView.Color>
</BoxView>
<BoxView>
<BoxView.Color>
<local:HslColor H="0.33" S="1" L="0.5" />
</BoxView.Color>
</BoxView>
ImageResourceExtension is helpful when a XAML file needs to access an image file stored as an embedded
resource in the .NET Standard library project. It uses the Source property to call the static
ImageSource.FromResource method. This method requires a fully-qualified resource name, which consists of the
assembly name, the folder name, and the filename separated by periods. The ImageResourceExtension doesn't need
the assembly name portion because it obtains the assembly name using reflection and prepends it to the Source
property. Regardless, ImageSource.FromResource must be called from the assembly that contains the bitmap, which
means that this XAML resource extension cannot be part of an external library unless the images are also in that
library. (See the Embedded Images article for more information on accessing bitmaps stored as embedded
resources.)
Although ImageResourceExtension requires the Source property to be set, the Source property is indicated in an
attribute as the content property of the class. This means that the Source= part of the expression in curly braces
can be omitted. In the Image Resource Demo page, the Image elements fetch two images using the folder name
and the filename separated by periods:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.ImageResourceDemoPage"
Title="Image Resource Demo">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
</Grid>
</ContentPage>
Service Providers
By using the IServiceProvider argument to ProvideValue , XAML markup extensions can get access to helpful
information about the XAML file in which they're being used. But to use the IServiceProvider argument
successfully, you need to know what kind of services are available in particular contexts. The best way to get an
understanding of this feature is by studying the source code of existing XAML markup extensions in the
MarkupExtensions folder in the Xamarin.Forms repository on GitHub. Be aware that some types of services are
internal to Xamarin.Forms.
In some XAML markup extensions, this service might be useful:
The IProvideValueTarget interface defines two properties, TargetObject and TargetProperty . When this
information is obtained in the ImageResourceExtension class, TargetObject is the Image and TargetProperty is a
BindableProperty object for the Source property of Image . This is the property on which the XAML markup
extension has been set.
The GetService call with an argument of typeof(IProvideValueTarget) actually returns an object of type
SimpleValueTargetProvider , which is defined in the Xamarin.Forms.Xaml.Internals namespace. If you cast the
return value of GetService to that type, you can also access a ParentObjects property, which is an array that
contains the Image element, the Grid parent, and the ImageResourceDemoPage parent of the Grid .
Conclusion
XAML markup extensions play a vital role in XAML by extending the ability to set attributes from a variety of
sources. Moreover, if the existing XAML markup extensions don't provide exactly what you need, you can also
write your own.
Related Links
Markup Extensions (sample)
XAML markup extensions chapter from Xamarin.Forms book
XAML Field Modifiers in Xamarin.Forms
6/20/2018 • 2 minutes to read • Edit Online
The x:FieldModifier namespace attribute specifies the access level for generated fields for named XAML
elements.
Overview
Valid values of the attribute are:
Public – specifies that the generated field for the XAML element is public .
NotPublic – specifies that the generated field for the XAML element is internal to the assembly.
If the value of the attribute isn't set, the generated field for the element will be private .
The following conditions must be met for an x:FieldModifier attribute to be processed:
The top-level XAML element must be a valid x:Class .
The current XAML element has an x:Name specified.
The following XAML shows examples of setting the attribute:
NOTE
The x:FieldModifier attribute cannot be used to specify the access level of a XAML class.
Passing Arguments in XAML
7/12/2018 • 3 minutes to read • Edit Online
This article demonstrates using the XAML attributes that can be used to pass arguments to non-default
constructors, to call factory methods, and to specify the type of a generic argument.
Overview
It's often necessary to instantiate objects with constructors that require arguments, or by calling a static creation
method. This can be achieved in XAML by using the x:Arguments and x:FactoryMethod attributes:
The x:Arguments attribute is used to specify constructor arguments for a non-default constructor, or for a
factory method object declaration. For more information, see Passing Constructor Arguments.
The x:FactoryMethod attribute is used to specify a factory method that can be used to initialize an object. For
more information, see Calling Factory Methods.
In addition, the x:TypeArguments attribute can be used to specify the generic type arguments to the constructor of
a generic type. For more information, see Specifying a Generic Type Argument.
The following code example demonstrates using the x:Arguments attribute with three Color constructors:
<BoxView HeightRequest="150" WidthRequest="150" HorizontalOptions="Center">
<BoxView.Color>
<Color>
<x:Arguments>
<x:Double>0.9</x:Double>
</x:Arguments>
</Color>
</BoxView.Color>
</BoxView>
<BoxView HeightRequest="150" WidthRequest="150" HorizontalOptions="Center">
<BoxView.Color>
<Color>
<x:Arguments>
<x:Double>0.25</x:Double>
<x:Double>0.5</x:Double>
<x:Double>0.75</x:Double>
</x:Arguments>
</Color>
</BoxView.Color>
</BoxView>
<BoxView HeightRequest="150" WidthRequest="150" HorizontalOptions="Center">
<BoxView.Color>
<Color>
<x:Arguments>
<x:Double>0.8</x:Double>
<x:Double>0.5</x:Double>
<x:Double>0.2</x:Double>
<x:Double>0.5</x:Double>
</x:Arguments>
</Color>
</BoxView.Color>
</BoxView>
The number of elements within the x:Arguments tag, and the types of these elements, must match one of the
Color constructors. The Color constructor with a single parameter requires a grayscale value from 0 (black) to 1
(white). The Color constructor with three parameters requires a red, green, and blue value ranging from 0 to 1.
The Color constructor with four parameters adds an alpha channel as the fourth parameter.
The following screenshots show the result of calling each Color constructor with the specified argument values:
Calling Factory Methods
Factory methods can be called in XAML by specifying the method's name using the x:FactoryMethod attribute,
and its arguments using the x:Arguments attribute. A factory method is a public static method that returns
objects or values of the same type as the class or structure that defines the methods.
The Color structure defines a number of factory methods, and the following code example demonstrates calling
three of them:
The number of elements within the x:Arguments tag, and the types of these elements, must match the arguments
of the factory method being called. The FromRgba factory method requires four Int32 parameters, which
represent the red, green, blue, and alpha values, ranging from 0 to 255 respectively. The FromHsla factory method
requires four Double parameters, which represent the hue, saturation, luminosity, and alpha values, ranging from
0 to 1 respectively. The FromHex factory method requires a String that represents the hexadecimal (A)RGB color.
The following screenshots show the result of calling each Color factory method with the specified argument
values:
Specifying a Generic Type Argument
Generic type arguments for the constructor of a generic type can be specified using the x:TypeArguments attribute,
as demonstrated in the following code example:
<ContentPage ...>
<StackLayout>
<StackLayout.Margin>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0,20,0,0" />
<On Platform="Android" Value="5, 10" />
<On Platform="UWP" Value="10" />
</OnPlatform>
</StackLayout.Margin>
</StackLayout>
</ContentPage>
The OnPlatform class is a generic class and must be instantiated with an x:TypeArguments attribute that matches
the target type. In the On class, the Platform attribute can accept a single string value, or multiple comma-
delimited string values. In this example, the StackLayout.Margin property is set to a platform-specific Thickness
.
Summary
This article demonstrated using the XAML attributes that can be used to pass arguments to non-default
constructors, to call factory methods, and to specify the type of a generic argument.
Related Links
XAML Namespaces
Passing Constructor Arguments (sample)
Calling Factory Methods (sample)
Bindable Properties
7/12/2018 • 8 minutes to read • Edit Online
In Xamarin.Forms, the functionality of common language runtime (CLR ) properties is extended by bindable
properties. A bindable property is a special type of property, where the property's value is tracked by the
Xamarin.Forms property system. This article provides an introduction to bindable properties, and demonstrates
how to create and consume them.
Overview
Bindable properties extend CLR property functionality by backing a property with a BindableProperty type,
instead of backing a property with a field. The purpose of bindable properties is to provide a property system that
supports data binding, styles, templates, and values set through parent-child relationships. In addition, bindable
properties can provide default values, validation of property values, and callbacks that monitor property changes.
Properties should be implemented as bindable properties to support one or more of the following features:
Acting as a valid target property for data binding.
Setting the property through a style.
Providing a default property value that's different from the default for the type of the property.
Validating the value of the property.
Monitoring property changes.
Examples of Xamarin.Forms bindable properties include Label.Text , Button.BorderRadius , and
StackLayout.Orientation . Each bindable property has a corresponding public static readonly property of type
BindableProperty that is exposed on the same class and that is the identifier of the bindable property. For
example, the corresponding bindable property identifier for the Label.Text property is Label.TextProperty .
This creates a BindablePropertyinstance named EventName , of type string . The property is owned by the
EventToCommandBehavior class, and has a default value of null . The naming convention for bindable properties is
that the bindable property identifier must match the property name specified in the Create method, with
"Property" appended to it. Therefore, in the example above, the bindable property identifier is EventNameProperty .
Optionally, when creating a BindableProperty instance, the following parameters can be specified:
The binding mode. This is used to specify the direction in which property value changes will propagate. In the
default binding mode, changes will propagate from the source to the target.
A validation delegate that will be invoked when the property value is set. For more information, see Validation
Callbacks.
A property changed delegate that will be invoked when the property value has changed. For more information,
see Detecting Property Changes.
A property changing delegate that will be invoked when the property value will change. This delegate has the
same signature as the property changed delegate.
A coerce value delegate that will be invoked when the property value has changed. For more information, see
Coerce Value Callbacks.
A Func that's used to initialize a default property value. For more information, see Creating a Default Value
with a Func.
Creating Accessors
Property accessors are required to use property syntax to access a bindable property. The Get accessor should
return the value that's contained in the corresponding bindable property. This can be achieved by calling the
GetValue method, passing in the bindable property identifier on which to get the value, and then casting the result
to the required type. The Set accessor should set the value of the corresponding bindable property. This can be
achieved by calling the SetValue method, passing in the bindable property identifier on which to set the value,
and the value to set.
The following code example shows accessors for the EventName bindable property:
The namespace declaration is used when setting the EventName bindable property, as demonstrated in the
following XAML code example:
<ListView ...>
<ListView.Behaviors>
<local:EventToCommandBehavior EventName="ItemSelected" ... />
</ListView.Behaviors>
</ListView>
Advanced Scenarios
When creating a BindableProperty instance, there are a number of optional parameters that can be set to enable
advanced bindable property scenarios. This section explores these scenarios.
Detecting Property Changes
A static property-changed callback method can be registered with a bindable property by specifying the
propertyChanged parameter for the BindableProperty.Create method. The specified callback method will be
invoked when the value of the bindable property changes.
The following code example shows how the EventName bindable property registers the OnEventNameChanged
method as a property-changed callback method:
In the property-changed callback method, the BindableObject parameter is used to denote which instance of the
owning class has reported a change, and the values of the two object parameters represent the old and new
values of the bindable property.
Validation Callbacks
A static validation callback method can be registered with a bindable property by specifying the validateValue
parameter for the BindableProperty.Create method. The specified callback method will be invoked when the value
of the bindable property is set.
The following code example shows how the Angle bindable property registers the IsValidValue method as a
validation callback method:
Validation callbacks are provided with a value, and should return true if the value is valid for the property,
otherwise false . An exception will be raised if a validation callback returns false , which should be handled by
the developer. A typical use of a validation callback method is constraining the values of integers or doubles when
the bindable property is set. For example, the IsValidValue method checks that the property value is a double
within the range 0 to 360.
Coerce Value Callbacks
A static coerce value callback method can be registered with a bindable property by specifying the coerceValue
parameter for the BindableProperty.Create method. The specified callback method will be invoked when the value
of the bindable property changes.
Coerce value callbacks are used to force a reevaluation of a bindable property when the value of the property
changes. For example, a coerce value callback can be used to ensure that the value of one bindable property is not
greater than the value of another bindable property.
The following code example shows how the Angle bindable property registers the CoerceAngle method as a
coerce value callback method:
return input;
}
The CoerceAngle method checks the value of the MaximumAngle property, and if the Angle property value is
greater than it, it coerces the value to the MaximumAngle property value.
Creating a Default Value with a Func
A Func can be used to initialize the default value of a bindable property, as demonstrated in the following code
example:
public static readonly BindableProperty SizeProperty =
BindableProperty.Create ("Size", typeof(double), typeof(HomePage), 0.0,
defaultValueCreator: bindable => Device.GetNamedSize (NamedSize.Large, (Label)bindable));
The defaultValueCreator parameter is set to a Func that invokes the Device.GetNamedSize method to return a
double that represents the named size for the font that is used on a Label on the native platform.
Summary
This article provided an introduction to bindable properties, and demonstrated how to create and consume them.
A bindable property is a special type of property, where the property's value is tracked by the Xamarin.Forms
property system.
Related Links
XAML Namespaces
Event To Command Behavior (sample)
Validation Callback (sample)
Coerce Value Callback (sample)
BindableProperty
BindableObject
Attached Properties
7/12/2018 • 4 minutes to read • Edit Online
An attached property is a special type of bindable property, defined in one class but attached to other objects, and
recognizable in XAML as an attribute that contains a class and a property name separated by a period. This
article provides an introduction to attached properties, and demonstrates how to create and consume them.
Overview
Attached properties enable an object to assign a value for a property that its own class doesn't define. For
example, child elements can use attached properties to inform their parent element of how they are to be
presented in the user interface. The Grid control allows the row and column of a child to be specified by setting
the Grid.Row and Grid.Column attached properties. Grid.Row and Grid.Column are attached properties because
they are set on elements that are children of a Grid , rather than on the Grid itself.
Bindable properties should be implemented as attached properties in the following scenarios:
When there's a need to have a property setting mechanism available for classes other than the defining class.
When the class represents a service that needs to be easily integrated with other classes.
For more information about bindable properties, see Bindable Properties.
An attached property can be created by declaring a public static readonly property of type BindableProperty .
The bindable property should be set to the returned value of one of the BindableProperty.CreateAttached method
overloads. The declaration should be within the body of the owning class, but outside of any member definitions.
The following code shows an example of an attached property:
This creates an attached property named HasShadow , of type bool . The property is owned by the ShadowEffect
class, and has a default value of false . The naming convention for attached properties is that the attached
property identifier must match the property name specified in the CreateAttached method, with "Property"
appended to it. Therefore, in the example above, the attached property identifier is HasShadowProperty .
For more information about creating bindable properties, including parameters that can be specified during
creation, see Creating and Consuming a Bindable Property.
Creating Accessors
Static Get PropertyName and Set PropertyName methods are required as accessors for the attached property,
otherwise the property system will be unable to use the attached property. The Get PropertyName accessor
should conform to the following signature:
The Get PropertyName accessor should return the value that's contained in the corresponding BindableProperty
field for the attached property. This can be achieved by calling the GetValue method, passing in the bindable
property identifier on which to get the value, and then casting the resulting value to the required type.
The Set PropertyName accessor should conform to the following signature:
The Set PropertyName accessor should set the value of the corresponding BindableProperty field for the
attached property. This can be achieved by calling the SetValue method, passing in the bindable property
identifier on which to set the value, and the value to set.
For both accessors, the target object should be of, or derive from, BindableObject .
The following code example shows accessors for the HasShadow attached property:
The namespace declaration is then used when setting the attached property on a specific control, as
demonstrated in the following XAML code example:
The Style can be applied to a Label by setting its Style property to the Style instance using the
StaticResource markup extension, as demonstrated in the following code example:
Advanced Scenarios
When creating an attached property, there are a number of optional parameters that can be set to enable
advanced attached property scenarios. This includes detecting property changes, validating property values, and
coercing property values. For more information, see Advanced Scenarios.
Summary
This article provided an introduction to attached properties, and demonstrated how to create and consume them.
An attached property is a special type of bindable property, defined in one class but attached to other objects, and
recognizable in XAML as attributes that contain a class and a property name separated by a period.
Related Links
Bindable Properties
XAML Namespaces
Shadow Effect (sample)
BindableProperty
BindableObject
Resource Dictionaries
6/21/2018 • 8 minutes to read • Edit Online
XAML resources are definitions of objects that can be shared and re-used throughout a Xamarin.Forms
application.
These resource objects are stored in a resource dictionary. This article describes how to create and consume a
resource dictionary, and how to merge resource dictionaries.
Overview
A ResourceDictionary is a repository for resources that are used by a Xamarin.Forms application. Typical
resources that are stored in a ResourceDictionary include styles, control templates, data templates, colors, and
converters.
In XAML, resources that are stored in a ResourceDictionary can then be retrieved and applied to elements by
using the StaticResource markup extension. In C#, resources can also be defined in a ResourceDictionary and
then retrieved and applied to elements by using a string-based indexer. However, there's little advantage to using a
ResourceDictionary in C#, as shared objects can simply be stored as fields or properties, and accessed directly
without having to first retrieve them from a dictionary.
A Xamarin.Forms program contains only one class that derives from Application but often makes use of many
classes that derive from VisualElement , including pages, layouts, and controls. Any of these objects can have its
Resources property set to a ResourceDictionary . Choosing where to put a particular ResourceDictionary impacts
where the resources can be used:
Resources in a ResourceDictionary that is attached to a view such as Button or Label can only be applied to
that particular object, so this is not very useful.
Resources in a ResourceDictionary attached to a layout such as StackLayout or Grid can be applied to the
layout and all the children of that layout.
Resources in a ResourceDictionary defined at the page level can be applied to the page and to all its children.
Resources in a ResourceDictionary defined at the application level can be applied throughout the application.
The following XAML shows resources defined in an application level ResourceDictionary in the App.xaml file
created as part of the standard Xamarin.Forms program:
<Application ...>
<Application.Resources>
<ResourceDictionary>
<Color x:Key="PageBackgroundColor">Yellow</Color>
<Color x:Key="HeadingTextColor">Black</Color>
<Color x:Key="NormalTextColor">Blue</Color>
<Style x:Key="LabelPageHeadingStyle" TargetType="Label">
<Setter Property="FontAttributes" Value="Bold" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="TextColor" Value="{StaticResource HeadingTextColor}" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
This ResourceDictionary defines three Color resources and a Style resource. For more information about the
App class, see App Class.
Beginning in Xamarin.Forms 3.0, the explicit ResourceDictionary tags are not required. The ResourceDictionary
object is created automatically, and you can insert the resources directly between the Resources property-element
tags:
<Application ...>
<Application.Resources>
<Color x:Key="PageBackgroundColor">Yellow</Color>
<Color x:Key="HeadingTextColor">Black</Color>
<Color x:Key="NormalTextColor">Blue</Color>
<Style x:Key="LabelPageHeadingStyle" TargetType="Label">
<Setter Property="FontAttributes" Value="Bold" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="TextColor" Value="{StaticResource HeadingTextColor}" />
</Style>
</Application.Resources>
</Application>
Each resource has a key that is specified using the x:Key attribute, which becomes it dictionary key in the
ResourceDictionary . The key is used to retrieve a resource from the ResourceDictionary by the StaticResource
markup extension, as demonstrated in the following XAML code example that shows additional resources defined
within the StackLayout :
<StackLayout Margin="0,20,0,0">
<StackLayout.Resources>
<ResourceDictionary>
<Style x:Key="LabelNormalStyle" TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource NormalTextColor}" />
</Style>
<Style x:Key="MediumBoldText" TargetType="Button">
<Setter Property="FontSize" Value="Medium" />
<Setter Property="FontAttributes" Value="Bold" />
</Style>
</ResourceDictionary>
</StackLayout.Resources>
<Label Text="ResourceDictionary Demo" Style="{StaticResource LabelPageHeadingStyle}" />
<Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries."
Margin="10,20,10,0"
Style="{StaticResource LabelNormalStyle}" />
<Button Text="Navigate"
Clicked="OnNavigateButtonClicked"
TextColor="{StaticResource NormalTextColor}"
Margin="0,20,0,0"
HorizontalOptions="Center"
Style="{StaticResource MediumBoldText}" />
</StackLayout>
The first Label instance retrieves and consumes the LabelPageHeadingStyle resource defined in the application
level ResourceDictionary , with the second Label instance retrieving and consuming the LabelNormalStyle
resource defined in the control level ResourceDictionary . Similarly, the Button instance retrieves and consumes
the NormalTextColor resource defined in the application level ResourceDictionary , and the MediumBoldText
resource defined in the control level ResourceDictionary . This results in the appearance shown in the following
screenshots:
NOTE
Resources that are specific to a single page shouldn't be included in an application level resource dictionary, as such
resources will then be parsed at application startup instead of when required by a page. For more information, see Reduce
the Application Resource Dictionary Size.
Overriding Resources
When ResourceDictionary resources share x:Key attribute values, resources defined lower in the view hierarchy
will take precedence over those defined higher up. For example, setting the PageBackgroundColor resource to
Blue at the application level will be overridden by a page level PageBackgroundColor resource set to Yellow .
Similarly, a page level PageBackgroundColor resource will be overridden by a control level PageBackgroundColor
resource. This precedence is demonstrated by the following XAML code example:
The original PageBackgroundColor and NormalTextColor instances, defined at the application level, are overridden
by the PageBackgroundColor and NormalTextColor instances defined at page level. Therefore, the page background
color becomes blue, and the text on the page becomes yellow, as demonstrated in the following screenshots:
However, note that the background bar of the NavigationPage is still yellow, because the BarBackgroundColor
property is set to the value of the PageBackgroundColor resource defined in the application level
ResourceDictionary .
Here's another way to think about ResourceDictionary precedence: When the XAML parser encounters a
StaticResource , it searches for a matching key by traveling up through the visual tree, using the first match it
finds. If this search ends at the page and the key still hasn't been found, the XAML parser searches the
ResourceDictionary attached to the App object. If the key is still not found, an exception is raised.
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ResourceDictionaryDemo.MyResourceDictionary">
<DataTemplate x:Key="PersonDataTemplate">
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.3*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}" TextColor="{StaticResource NormalTextColor}"
FontAttributes="Bold" />
<Label Grid.Column="1" Text="{Binding Age}" TextColor="{StaticResource NormalTextColor}" />
<Label Grid.Column="2" Text="{Binding Location}" TextColor="{StaticResource NormalTextColor}"
HorizontalTextAlignment="End" />
</Grid>
</ViewCell>
</DataTemplate>
</ResourceDictionary>
<ContentPage ...>
<ContentPage.Resources>
<local:MyResourceDictionary />
</ContentPage.Resources>
...
</ContentPage>
IMPORTANT
ResourceDictionary also defines a MergedWith property. Do not use this property; it has been deprecated as of
Xamarin.Forms 3.0.
And instance of can be merged into any application, page, or control level
MyResourceDictionary
ResourceDictionary . The following XAML code example shows it being merged into a page level
ResourceDictionary using the MergedDictionaries property:
<ContentPage ...>
<ContentPage.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<local:MyResourceDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ContentPage.Resources>
...
</ContentPage>
That markup shows only an instance of MyResourceDictionary being added to the ResourceDictionary but you can
also reference other ResourceDictionary instances within the MergedDictionary property-element tags, and other
resources outside of those tags:
<ContentPage ...>
<ContentPage.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<local:MyResourceDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ContentPage.Resources>
...
</ContentPage>
There can be only one MergedDictionaries section in a ResourceDictionary , but you can put as many
ResourceDictionary instances in there as you want.
When merged ResourceDictionary resources share identical x:Key attribute values, Xamarin.Forms uses the
following resource precedence:
1. The resources local to the resource dictionary.
2. The resources contained in the resource dictionary that was merged via the deprecated MergedWith property.
3. The resources contained in the resource dictionaries that were merged via the MergedDictionaries collection,
in the reverse order they are listed in the MergedDictionaries property.
NOTE
Searching resource dictionaries can be a computationally intensive task if an application contains multiple, large resource
dictionaries. Therefore, to avoid unnecessary searching, you should ensure that each page in an application only uses
resource dictionaries that are appropriate to the page.
<ContentPage ...>
<ContentPage.Resources>
<ResourceDictionary>
</ResourceDictionary>
</ContentPage.Resources>
...
</ContentPage>
Because Xamarin.Forms 3.0 automatically instantiates the ResourceDictionary , those two outer
ResourceDictionary tags are no longer required:
<ContentPage ...>
<ContentPage.Resources>
</ContentPage.Resources>
...
</ContentPage>
This new syntax does not instantiate the MyResourceDictionary class. Instead, it references the XAML file. For that
reason the code-behind file (MyResourceDictionary.xaml.cs) is no longer required. You can also remove the
x:Class attribute from the root tag of the MyResourceDictionary.xaml file.
Summary
This article explained how to create and consume a ResourceDictionary , and how to merge resource dictionaries.
A ResourceDictionary allows resources to be defined in a single location, and re-used throughout a
Xamarin.Forms application.
Related Links
Resource Dictionaries (sample)
Styles
ResourceDictionary
XAML Standard (Preview)
6/8/2018 • 2 minutes to read • Edit Online
Related Links
Preview NuGet
Controls Reference
XAML Standard (Preview) Controls
6/8/2018 • 2 minutes to read • Edit Online
This page lists the XAML Standard controls available in the Preview, alongside their equivalent Xamarin.Forms
control.
There is also a list of controls that have new property and enumeration names in XAML Standard.
Controls
XAMARIN.FORMS XAML STANDARD
Frame Border
Picker ComboBox
ActivityIndicator ProgressRing
StackLayout StackPanel
Label TextBlock
Entry TextBox
Switch ToggleSwitch
ContentView UserControl
Button, Entry, Label, Editor, SearchBar, FontAttributesBold, Italic, None FontStyleItalic, Normal
Span, Font
IMPORTANT
Items marked with * are incomplete in the current preview
Related Links
Preview NuGet
Xamarin.Forms Application Fundamentals
7/12/2018 • 2 minutes to read • Edit Online
Accessibility
Tips to incorporate accessible features (like supporting screen-reading tools) with Xamarin.Forms.
App Class
The Application class is the starting point for Xamarin.Forms – every app needs to implement a subclass App to
set the initial page. It also provides the Properties collection for simple data storage. It can be defined in either C#
or XAML.
App Lifecycle
The Application class OnStart , OnSleep , and OnResume methods, as well as modal navigation events, let you
handle application lifecycle events with custom code.
Behaviors
User interface controls can be easily extended without subclassing by using behaviors to add functionality.
Custom Renderers
Custom Renders let developers 'override' the default rendering of Xamarin.Forms controls to customize their
appearance and behavior on each platform (using native SDKs if desired).
Data Binding
Data binding links the properties of two objects, allowing changes in one property to be automatically reflected in
the other property. Data binding is an integral part of the Model-View -ViewModel (MVVM ) application
architecture.
Dependency Service
The DependencyService provides a simple locator so that you can code to interfaces in your shared code and
provide platform-specific implementations that are automatically resolved, making it easy to reference platform-
specific functionality in Xamarin.Forms.
Effects
Effects allow the native controls on each platform to be customized, and are typically used for small styling
changes.
Files
File handling with Xamarin.Forms can be achieved using code in a .NET Standard library, or by using embedded
resources.
Gestures
The Xamarin.Forms GestureRecognizer class supports tap, pinch, and pan gestures on user interface controls.
Localization
The built-in .NET localization framework can be used to build cross-platform multilingual applications with
Xamarin.Forms.
Local Databases
Xamarin.Forms supports database-driven applications using the SQLite database engine, which makes it possible
to load and save objects in shared code.
Messaging Center
Xamarin.Forms MessagingCenter enables view models and other components to communicate with without having
to know anything about each other besides a simple Message contract.
Navigation
Xamarin.Forms provides a number of different page navigation experiences, depending upon the Page type being
used.
Templates
Control templates provide the ability to easily theme and re-theme application pages at runtime, while data
templates provide the ability to define the presentation of data on supported controls.
Triggers
Update controls by responding to property changes and events in XAML.
Related Links
Introduction To Xamarin.Forms
Xamarin.Forms Accessibility
6/8/2018 • 2 minutes to read • Edit Online
Building an accessible application ensures that the application is usable by people who approach the user interface
with a range of needs and experiences.
Making a Xamarin.Forms application accessible means thinking about the layout and design of many user
interface elements. For guidelines on issues to consider, see the Accessibility Checklist. Many accessibility concerns
such as large fonts, and suitable color and contrast settings can already be addressed by Xamarin.Forms APIs.
The Android accessibility and iOS accessibility guides contain details of the native APIs exposed by Xamarin, and
the UWP accessibility guide on MSDN explains the native approach on that platform. These APIs are used to fully
implement accessible applications on each platform.
Xamarin.Forms does not currently have built-in support for all of the accessibility APIs available on each of the
underlying platforms. However, it does support setting accessibility values on user interface elements to support
screen reader and navigation assistance tools, which is one of the most important parts of building accessible
applications. For more information, see Setting Accessibility Values on User Interface Elements.
Other accessibility APIs (such as PostNotification on iOS ) may be better suited to a DependencyService or Custom
Renderer implementation. These are not covered in this guide.
Testing Accessibility
Xamarin.Forms applications typically target multiple platforms, which means testing the accessibility features
according to the platform. Follow these links to learn how to test accessibility on each platform:
iOS Testing
Android Testing
Windows AccScope (MSDN )
Related Links
Cross-platform Accessibility
Setting Accessibility Values on User Interface Elements
Setting Accessibility Values on User Interface
Elements
7/12/2018 • 4 minutes to read • Edit Online
Xamarin.Forms allows accessibility values to be set on user interface elements by using attached properties from
the AutomationProperties class, which in turn set native accessibility values. This article explains how to use the
AutomationProperties class, so that a screen reader can speak about the elements on the page.
Overview
Xamarin.Forms allows accessibility values to be set on user interface elements via the following attached
properties:
AutomationProperties.IsInAccessibleTree – indicates whether the element is availa