1

Relatively new to using ControlTemplates so this may be a super easy question. But I have footer that I use on several pages, so I think a ControlTemplate would be a good idea. First problem I'm running into though is how to make the image path binded.

Here is my App.xaml file

<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:abstractions="clr-namespace:SVG.Forms.Plugin.Abstractions;assembly=SVG.Forms.Plugin.Abstractions" x:Class="MyApp.App"> <Application.Resources> <ResourceDictionary> <Style x:Key="HomeButtonStyle" TargetType="Button"> <Setter Property="FontSize" Value="Medium" /> <Setter Property="TextColor" Value="White" /> <Setter Property="FontAttributes" Value="Bold"/> <Setter Property="BorderWidth" Value="1"/> <Setter Property="BorderColor" Value="White"/> <Setter Property="BorderRadius" Value="5"/> <Setter Property="Margin" Value="16,16,16,0"/> </Style> <ControlTemplate x:Key="Menu"> <StackLayout Orientation="Horizontal" VerticalOptions="End" BackgroundColor="Black" HeightRequest="70" HorizontalOptions="FillAndExpand" Spacing="20"> <abstractions:SvgImage x:Name="Settings" SvgAssembly="{Binding SvgAssembly}" SvgPath="{Binding SettingsIcon}" HeightRequest="50" WidthRequest="50" BackgroundColor="Transparent" VerticalOptions="Center" HorizontalOptions="CenterAndExpand"/> <abstractions:SvgImage x:Name="Notification" SvgAssembly="{Binding SvgAssembly}" SvgPath="{Binding Notification}" HeightRequest="50" WidthRequest="50" BackgroundColor="Transparent" VerticalOptions="Center" HorizontalOptions="CenterAndExpand"/> <abstractions:SvgImage x:Name="Help" SvgAssembly="{Binding SvgAssembly}" SvgPath="{Binding HelpIcon}" HeightRequest="50" WidthRequest="50" BackgroundColor="Transparent" VerticalOptions="Center" HorizontalOptions="CenterAndExpand"/> </StackLayout> </ControlTemplate> </ResourceDictionary> </Application.Resources> 

And then how I am trying to use it (HomePage.xaml)...

<?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:abstractions="clr-namespace:SVG.Forms.Plugin.Abstractions;assembly=SVG.Forms.Plugin.Abstractions" x:Class="Page.HomePage"> <StackLayout> ... <ContentView ControlTemplate="{StaticResource Menu}"></ContentView> </StackLayout> </ContentPage> 

Here is my HomePage.xaml.cs file...

public partial class HomePage : ContentPage { public HomePage() { InitializeComponent(); BindingContext = new SvgImagesViewModels(); } } 

And the ViewModel

public class SvgImagesViewModels { private readonly string _os = DeviceInfo.Hardware.OS == OperatingSystemType.iOS ? "iOS.Images" : "Droid.Images"; 
 /* The Assembly */ public Assembly SvgAssembly => typeof(App).GetTypeInfo().Assembly; /* The Image Paths */ public string UserAvatar => $"{_os}.avatar.svg"; public string Notification => $"{_os}.bell.svg"; public string RedNotification => $"{_os}.red_bell.svg"; public string Delete => $"{_os}.delete.svg"; public string HelpIcon => $"{_os}.help.svg"; public string Home => $"{_os}.home.svg"; public string SettingsIcon => $"{_os}.settings.svg"; public string NoImage => $"{_os}.no_image.svg"; public string Star => $"{_os}.star.svg"; public string DownCarrot => $"{_os}.down_carrot.svg"; public string UpCattor => $"{_os}.up_carrot.svg"; public string RightCarrot => $"{_os}.right_carrot.svg"; public string LeftCarrot => $"{_os}.left_carrot.svg"; } 

And here is the error I am getting...

09-14 20:07:22.428 E/mono-rt (11715): [ERROR] FATAL UNHANDLED EXCEPTION: System.AggregateException: One or more errors occurred. ---> System.NullReferenceException: Object reference not set to an instance of an object. 09-14 20:07:22.428 E/mono-rt (11715): at SVG.Forms.Plugin.Droid.SvgImageRenderer+<<OnElementChanged>b__3_0>d.MoveNext () [0x00020] in <filename unknown>:0 09-14 20:07:22.428 E/mono-rt (11715): --- End of inner exception stack trace --- 09-14 20:07:22.428 E/mono-rt (11715): at (wrapper dynamic-method) System.Object:b7e27031-315a-4ca4-9b10-5b1ac793598c (intptr,intptr) 09-14 20:07:22.428 E/mono-rt (11715): at (wrapper native-to-managed) System.Object:b7e27031-315a-4ca4-9b10-5b1ac793598c (intptr,intptr) 09-14 20:07:22.428 E/mono-rt (11715): ---> (Inner Exception #0) System.NullReferenceException: Object reference not set to an instance of an object. 09-14 20:07:22.428 E/mono-rt (11715): at SVG.Forms.Plugin.Droid.SvgImageRenderer+<<OnElementChanged>b__3_0>d.MoveNext () [0x00020] in <filename unknown>:0 <--- 

So obviously I am trying to apply the BindingContext incorrectly.

1 Answer 1

1

in your ControlTemplate, you should use {TemplateBinding}, like this:

<ResourceDictionary> ... <ControlTemplate x:Key="Menu"> <StackLayout> <abstractions:SvgImage SvgAssembly="{TemplateBinding SvgAssembly}" SvgPath="{TemplateBinding SettingsIcon}" /> ... </StackLayout> </ControlTemplate> </ResourceDictionary> 

But now that you have TemplateBindings, you need to define your own templatable Control

public class Menu : ContentView { public static BindableProperty SvgAssemblyProperty = BindableProperty.Create("SvgAssembly", typeof(Assembly), typeof(Menu), null); public static BindableProperty SettingsIconProperty = BindableProperty.Create("SettingsIcon", typeof(string), typeof(Menu), null); ... } 

and you can then use it, and bind to 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:abstractions="clr-namespace:SVG.Forms.Plugin.Abstractions;assembly=SVG.Forms.Plugin.Abstractions" x:Class="Page.HomePage"> <StackLayout> ... <Menu ControlTemplate="{StaticResource Menu} SvgAssembly="{Binding SvgAssmbly}" SettingsIcon="{Binding SettingsIcon}" .../> </StackLayout> </ContentPage> 

This should answer your question. Now, if all you're trying to do is to have different icons for each platform, using ControlTemplate is overkill. You could use OnPlatform, or use `{x:Static}, or probably 4-5 different ways. Have fun experimenting...

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! It doesn't seem like I will be saving much though with using the Control Template. Time to investigate

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.