{"id":24886,"date":"2016-03-08T11:00:15","date_gmt":"2016-03-08T19:00:15","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=24886"},"modified":"2016-03-08T11:00:15","modified_gmt":"2016-03-08T19:00:15","slug":"app-theming-with-xamarin-forms-control-templates","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/app-theming-with-xamarin-forms-control-templates\/","title":{"rendered":"App Theming with Xamarin.Forms Control Templates"},"content":{"rendered":"<p>\t\t\t\tControls have different properties, such as <code>BackgroundColor<\/code> and <code>TextColor<\/code>, that can define aspects of the control&#8217;s appearance. These properties can be set using <a href=\"https:\/\/developer.xamarin.com\/guides\/xamarin-forms\/user-interface\/styles\/\" target=\"_blank\">styles<\/a>, which can be changed at runtime in order to implement basic theming. We have already looked at <a href=\"https:\/\/blog.xamarin.com\/easy-app-theming-with-xamarin-forms-styles\/\">theming applications with styles<\/a>. However, styles don&#8217;t maintain a clean separation between the appearance of a page and its content, and the changes that can be made by setting such properties are limited.<\/p>\n<p>Control templates provide a clean separation between the appearance of a page and its content, therefore enabling the creation of pages that can easily be themed. For example, an application may contain application level control templates that provide a dark theme and a light theme. Each <code>ContentPage<\/code> in the application can be themed by applying one of the control templates, without changing the content being displayed by the\u00a0page. In addition, the themes provided by control templates aren&#8217;t limited to changing the properties of controls. They can also change the controls used to implement the theme.<\/p>\n<p>In this blog post, I\u2019m going to explore using control templates to theme and re-theme application pages at runtime.<\/p>\n<h2>Introduction to Control Templates<\/h2>\n<p>A <code>ControlTemplate<\/code> specifies the appearance of a page or view and contains a root layout and, within that layout, the controls that implement the template. Typically, a <code>ControlTemplate<\/code> will utilize a <code>ContentPresenter<\/code> to mark where the content to be displayed by the page or view will appear. The page or view that consumes the <code>ControlTemplate<\/code> will then define content to be displayed by the <code>ContentPresenter<\/code>.<\/p>\n<p>A <code>ControlTemplate<\/code> can be applied to the following types by setting their <code>ControlTemplate<\/code> properties:<\/p>\n<ul>\n<li><code>ContentPage<\/code><\/li>\n<li><code>ContentView<\/code><\/li>\n<li><code>TemplatedPage<\/code><\/li>\n<li><code>TemplatedView\u00a0<\/code><\/li>\n<\/ul>\n<p>When a <code>ControlTemplate<\/code> is created and assigned to these types, any existing appearance is replaced with the appearance defined in the <code>ControlTemplate<\/code>.<\/p>\n<p>Control templates created in XAML are defined in a <code>ResourceDictionary<\/code> that&#8217;s assigned to the <code>Resources<\/code> collection of a page, or more typically to the <code>Resources<\/code> collection of the application. Control templates lower in the view hierarchy take precedence over those defined higher up. For example, a <code>ControlTemplate<\/code> named <code>DarkTheme<\/code> that&#8217;s defined at the page level will take precedence over an identically named template defined at the application level.<\/p>\n<h2>Creating a ControlTemplate<\/h2>\n<p>To define a <code>ControlTemplate<\/code> at the application level, a <code>ResourceDictionary<\/code> must be added to the <code>App<\/code> class, as shown in the following code example from the <a href=\"https:\/\/github.com\/xamarin\/xamarin-forms-samples\/tree\/master\/Templates\/ControlTemplates\" target=\"_blank\">sample application<\/a>:<\/p>\n<pre class=\"lang:xml decode:true\" title=\"App class\">&lt;Application ... x:Class=\"SimpleTheme.App\"&gt;\n    &lt;Application.Resources&gt;\n        &lt;ResourceDictionary&gt;\n            &lt;ControlTemplate x:Key=\"TealTemplate\"&gt;\n                &lt;Grid&gt;\n                    ...\n                    &lt;BoxView ... \/&gt;\n                    &lt;Label Text=\"Control Template Demo App\"\n                           TextColor=\"White\"\n                           VerticalOptions=\"Center\" ... \/&gt;\n                    &lt;ContentPresenter ... \/&gt;\n                    &lt;BoxView Color=\"Teal\" ... \/&gt;\n                    &lt;Label Text=\"(c) Xamarin 2016\"\n                           TextColor=\"White\"\n                           VerticalOptions=\"Center\" ... \/&gt;\n                &lt;\/Grid&gt;\n            &lt;\/ControlTemplate&gt;\n            &lt;ControlTemplate x:Key=\"AquaTemplate\"&gt;\n                ...\n            &lt;\/ControlTemplate&gt;\n        &lt;\/ResourceDictionary&gt;\n    &lt;\/Application.Resources&gt;\n&lt;\/Application&gt;<\/pre>\n<p>Each <code>ControlTemplate<\/code> instance is created as a reusable object in a <code>ResourceDictionary<\/code>. This is achieved by giving each declaration a unique <code>x:Key<\/code> attribute, which provides it with a descriptive key in the <code>ResourceDictionary<\/code>.<\/p>\n<p>The following code example shows a <code>ContentPage<\/code> applying the <code>TealTemplate<\/code> to the <code>ContentView<\/code>:<\/p>\n<pre class=\"lang:xml decode:true\" title=\"HomePage class\">&lt;ContentPage ... x:Class=\"SimpleTheme.HomePage\"&gt;\n    &lt;ContentView x:Name=\"contentView\" Padding=\"0,20,0,0\"\n                 ControlTemplate=\"{StaticResource TealTemplate}\"&gt;\n        &lt;StackLayout VerticalOptions=\"CenterAndExpand\"&gt;\n            &lt;Label Text=\"Welcome to the app!\" HorizontalOptions=\"Center\" \/&gt;\n            &lt;Button Text=\"Change Theme\" Clicked=\"OnButtonClicked\" \/&gt;\n        &lt;\/StackLayout&gt;\n    &lt;\/ContentView&gt;\n&lt;\/ContentPage&gt;<\/pre>\n<p>The <code>TealTemplate<\/code> is assigned to the <code>ContentView.ControlTemplate<\/code> property by using the <code>StaticResource<\/code> markup extension. The <code>ContentView.Content<\/code> property is set to a <code>StackLayout<\/code> that defines the content to be displayed on the <code>ContentPage<\/code>. This content will be displayed by the <code>ContentPresenter<\/code> contained in the <code>TealTemplate<\/code>. This results in the appearance shown in the following screenshots:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-24887\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Teal-Screenshots.png\" alt=\"Teal-Screenshots\" width=\"1280\" height=\"768\" \/><\/p>\n<h2>Re-theming an Application at Runtime<\/h2>\n<p>Clicking the <strong>Change Theme<\/strong> button executes the <code>OnButtonClicked<\/code> method, which is shown in the following code example from the <a href=\"https:\/\/github.com\/xamarin\/xamarin-forms-samples\/tree\/master\/Templates\/ControlTemplates\" target=\"_blank\">sample application<\/a>:<\/p>\n<pre class=\"lang:c# decode:true\" title=\"OnButtonClicked method\">void OnButtonClicked (object sender, EventArgs e)\n{\n  originalTemplate = !originalTemplate;\n  contentView.ControlTemplate = (originalTemplate) ? tealTemplate : aquaTemplate;\n}<\/pre>\n<p>This method replaces the active <code>ControlTemplate<\/code> instance with the alternative <code>ControlTemplate<\/code> instance, resulting in the following screenshot:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-24888\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Aqua-Screenshots.png\" alt=\"Aqua-Screenshots\" width=\"1280\" height=\"768\" \/><\/p>\n<h2>Extending a ControlTemplate with a TemplateBinding<\/h2>\n<p>Template bindings allow controls in a control template to data bind to public properties, enabling property values on controls in the control template to be easily changed. A <code>TemplateBinding<\/code> is similar to an existing <code>Binding<\/code>, except that the source of a <code>TemplateBinding<\/code> is always automatically set to the <em>parent<\/em> of the target view that owns the control template.<\/p>\n<p>In XAML, a <code>TemplateBinding<\/code> is created using the <code>TemplateBinding<\/code> markup extension, as demonstrated in the following code example from the <a href=\"https:\/\/github.com\/xamarin\/xamarin-forms-samples\/tree\/master\/Templates\/ControlTemplates\" target=\"_blank\">sample application<\/a>:<\/p>\n<pre class=\"lang:xml decode:true\" title=\"TealTemplate\">&lt;ControlTemplate x:Key=\"TealTemplate\"&gt;\n  &lt;Grid&gt;\n    ...\n    &lt;Label Text=\"{TemplateBinding Parent.HeaderText}\" ... \/&gt;\n    ...\n    &lt;Label Text=\"{TemplateBinding Parent.FooterText}\" ... \/&gt;\n  &lt;\/Grid&gt;\n&lt;\/ControlTemplate&gt;<\/pre>\n<p>Rather than set the <code>Label.Text<\/code> properties to static text, the properties\u00a0use template bindings to bind to bindable properties on the parent of the target view that owns the <code>ControlTemplate<\/code>. However, note that the template bindings bind to <code>Parent.HeaderText<\/code> and <code>Parent.FooterText<\/code>, rather than <code>HeaderText<\/code> and <code>FooterText<\/code>. This is because in the <a href=\"https:\/\/github.com\/xamarin\/xamarin-forms-samples\/tree\/master\/Templates\/ControlTemplates\" target=\"_blank\">sample application<\/a>, the bindable properties are defined on the grandparent of the target view, rather than the parent, as demonstrated in the following code example from the sample application:<\/p>\n<pre class=\"lang:c# decode:true \" title=\"TemplateBinding properties\">public static readonly BindableProperty HeaderTextProperty =\n  BindableProperty.Create (\"HeaderText\", typeof(string), typeof(HomePage), \"Control Template Demo App\");\npublic static readonly BindableProperty FooterTextProperty =\n  BindableProperty.Create (\"FooterText\", typeof(string), typeof(HomePage), \"(c) Xamarin 2016\");\n\npublic string HeaderText {\n  get { return (string)GetValue (HeaderTextProperty); }\n}\n\npublic string FooterText {\n  get { return (string)GetValue (FooterTextProperty); }\n}<\/pre>\n<p>This results in the appearance shown in the following screenshots:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-24887\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Teal-Screenshots.png\" alt=\"Teal-Screenshots\" width=\"1280\" height=\"768\" \/><\/p>\n<p>While these screenshots are identical to earlier screenshots, here the two <code>Label<\/code> instances in the control template have their <code>Text<\/code> properties set through a template binding, rather than being hard coded inside the template.<\/p>\n<h2>Wrapping Up<\/h2>\n<p>Control templates provide a clean separation between the appearance of a page and its content, therefore enabling the creation of pages that can easily be themed and re-themed at runtime.\u00a0Control templates can use template bindings to allow controls in the template to data bind to public properties, allowing\u00a0property values on controls in the control template to be easily changed.<\/p>\n<p>For more information about control templates, see our <a href=\"https:\/\/developer.xamarin.com\/guides\/xamarin-forms\/templates\/control-templates\/\">Control Templates Guide<\/a>.\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Controls have different properties, such as BackgroundColor and TextColor, that can define aspects of the control&#8217;s appearance. These properties can be set using styles, which can be changed at runtime in order to implement basic theming. We have already looked at theming applications with styles. However, styles don&#8217;t maintain a clean separation between the appearance [&hellip;]<\/p>\n","protected":false},"author":543,"featured_media":24887,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[4,16],"class_list":["post-24886","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-xamarin-platform","tag-xamarin-forms"],"acf":[],"blog_post_summary":"<p>Controls have different properties, such as BackgroundColor and TextColor, that can define aspects of the control&#8217;s appearance. These properties can be set using styles, which can be changed at runtime in order to implement basic theming. We have already looked at theming applications with styles. However, styles don&#8217;t maintain a clean separation between the appearance [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/24886","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/543"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=24886"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/24886\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=24886"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=24886"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=24886"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}