StackLayout

Because Xamarin cannot have more than a single widget/control per ContentPage, another element is needed: the StackLayout. With this it is possible to have multiple children in place. Notice the BackgroundColor attribute of the ContentPage element which changes the color of the screen and Slider is a widget/control.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
			 xmlns:local="clr-namespace:HelloXamarinForms"
			 x:Class="HelloXamarinForms.MainPageXaml"
			 BackgroundColor="#CCCCCC">

	<StackLayout VerticalOptions="Center" HorizontalOptions="Center">

		<Button Text="Click Here!" Clicked="Button_Clicked" />
		<Slider />

	</StackLayout>
	
</ContentPage>

Now, have the Slider change the opacity of the button. Add a ValueChanged="Slider_Changed" attribute to the Slider and give the Button a name using the x:Name attribute. This allows the C# code to access it.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
			 xmlns:local="clr-namespace:HelloXamarinForms"
			 x:Class="HelloXamarinForms.MainPageXaml">

	<StackLayout VerticalOptions="Center" HorizontalOptions="Center">

		<Button x:Name="bttn" Text="Click Here!" Opacity="1" Clicked="Button_Clicked" />
		<Slider ValueChanged="Slider_Changed" />

	</StackLayout>
	
</ContentPage>
using Xamarin.Forms;

namespace HelloXamarinForms
{
	public partial class MainPageXaml : ContentPage
	{
		public MainPageXaml()
		{
			InitializeComponent();
		}

		void Button_Clicked(object sender, System.EventArgs e)
		{
			DisplayAlert("Xamarin Forms", "Hello Xamarin Forms!", "OK");
			((Button)sender).Text = "Clicked!";
		}

		void Slider_Changed(object sender, ValueChangedEventArgs e)
		{
			bttn.Opacity = e.NewValue;
		}
	}
}

Data Binding

Through data binding, more can be done in XAML and less coding is needed. It always has a source and a target. The source is a property of an object that changes dynamically at run time. When the property changes, the data binding updates the target (a property of another object).

The source must implement the INotifyPropertyChanged interface and all the visual elements in Xamarin.Forms implements this inteface via BindableObject. INotifyPropertyChanged is covered in greater depth later in this tutorial. The bottom line is that data bindings can be created between the visual objects (widgets/controls) and properties.

To set up data binding in XAML:

  1. Set BindingContext of the target element (the Button) to x:Reference referencing the source element (Slider).
  2. Set the target property (the Opacity property of the Button) to reference the source property (the Value property of the Slider).

Example Code

This code continues from the previous section.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
			 xmlns:local="clr-namespace:HelloXamarinForms"
			 x:Class="HelloXamarinForms.MainPageXaml">

	<StackLayout VerticalOptions="Center" HorizontalOptions="Center">

		<Button Text="Click Here!"
				BindingContext="{x:Reference Name=sldr}"
				Opacity="{Binding Path=Value}"
				Clicked="Button_Clicked" />
		<Slider x:Name="sldr" />

	</StackLayout>
	
</ContentPage>

Remove the Slider_Changed() method from the C# code.


	public partial class MainPageXaml : ContentPage
	{
		public MainPageXaml()
		{
			InitializeComponent();
		}

		void Button_Clicked(object sender, System.EventArgs e)
		{
			DisplayAlert("Xamarin Forms", "Hello Xamarin Forms!", "OK");
			((Button)sender).Text = "Clicked!";
		}

		/*
		void Slider_Changed(object sender, ValueChangedEventArgs e)
		{
			bttn.Opacity = e.NewValue;
		}
		//*/
	}
}

The XAML file can be rewritten to do the same thing.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
			 xmlns:local="clr-namespace:HelloXamarinForms"
			 x:Class="HelloXamarinForms.MainPageXaml">

	<StackLayout VerticalOptions="Center" HorizontalOptions="Center">

		<Button Text="Click Here!"
				Opacity="{Binding Source={x:Reference sldr}, Path=Value}"
				Clicked="Button_Clicked" />
		<Slider x:Name="sldr" />

	</StackLayout>
	
</ContentPage>

Adding a BoxView and having its opacity change is now very a simple procedure. The BoxView is very simple and is explained later.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
			 xmlns:local="clr-namespace:HelloXamarinForms"
			 x:Class="HelloXamarinForms.MainPageXaml">

	<StackLayout VerticalOptions="Center" HorizontalOptions="Center">

		<Button Text="Click Here!"
				Opacity="{Binding Source={x:Reference sldr}, Path=Value}"
				Clicked="Button_Clicked" />
		<BoxView Color="Blue"
				Opacity="{Binding Source={x:Reference sldr}, Path=Value}" />
		<Slider x:Name="sldr" />

	</StackLayout>
	
</ContentPage>

It is possible to clean up the XAML even more by adding a BindingContext attribute (property) to the StackLayout and all the child elements inherit it. Now notice the Opacity attributes.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
			 xmlns:local="clr-namespace:HelloXamarinForms"
			 x:Class="HelloXamarinForms.MainPageXaml">

	<StackLayout BindingContext="{x:Reference sldr}"
					VerticalOptions="Center"
					HorizontalOptions="Center">

		<Button Text="Click Here!"
					 Opacity="{Binding Value}"
					 Clicked="Button_Clicked" />
		<BoxView Color="Blue"
					Opacity="{Binding Value}" />
		<Slider x:Name="sldr" />

	</StackLayout>
	
</ContentPage>

The Page has a BindingContext property, too.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
			 xmlns:local="clr-namespace:HelloXamarinForms"
			 x:Class="HelloXamarinForms.MainPageXaml"
			 BindingContext="{x:Reference sldr}">

	<StackLayout VerticalOptions="Center"
					HorizontalOptions="Center">

		<Button Text="Click Here!"
					 Opacity="{Binding Value}"
					 Clicked="Button_Clicked" />
		<BoxView Color="Blue"
					Opacity="{Binding Value}" />
		<Slider x:Name="sldr" />

	</StackLayout>

</ContentPage>
<< < [Page 2 of 11] > >>