Reputation: 979
Xamarin Newbie here. I need to avoid duplicating controls and layout in an app so I've tried to use Control Templates to achieve this. However, according to the examples in the previous link (source code here), I always need to include a ControlTemplate
property with the mark up on each page that I want to consume the control on.
Is this necessary or can i create the control separately in a content view and reference it within the body of the page I wish to add it to? I've gone down this route as I'll need to add parameters when calling the control from different pages. Is this the correct approach? This will primarily be for android and ios apps if that makes any difference.
Having t add the Control template layout on each page that needs is seems counter intuitive to the write-once-use-everywhere rationale i'm trying to go with.
Upvotes: 0
Views: 949
Reputation: 979
Thanks Leon Lu.
I didn't want to add the template in App.xaml as that would get cumbersome the more templates I added. I ended up creating a separate content-view with the control layout I wanted and used it directly in each page that needed it like so:
<ContentPage.Resources>
<ControlTemplate x:Key="StellaControlTemplate">
<controls:MyTemplate></controls:MyTemplate>
</ControlTemplate>
</ContentPage.Resources>
<StackLayout Spacing="10" x:Name="layout">
<Label Text="My template below"></Label>
<controls:MyTemplate PicForTemplate="harold.png"
ControlTemplate="{StaticResource StellaControlTemplate}">
</controls:MyTemplate>
</StackLayout>
Upvotes: 0
Reputation: 9234
I always need to include a ControlTemplate property with the mark up on each page that I want to consume the control on.
No, you can put your ControlTemplate
in the Application.Resources
tab of App.xaml
like following code.
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ControlTemplateDemos.App">
<Application.Resources>
<ControlTemplate x:Key="CardViewControlTemplate">
<!--
In this example, the frame's BindingContext is set to the control instance that the template is applied to. Therefore,
the binding expressions resolve against the properties of each CardView object.
-->
<Frame BindingContext="{Binding Source={RelativeSource TemplatedParent}}"
BackgroundColor="{Binding CardColor}"
BorderColor="{Binding BorderColor}"
CornerRadius="5"
HasShadow="True"
Padding="8"
HorizontalOptions="Center"
VerticalOptions="Center">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="75" />
<RowDefinition Height="4" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="75" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<Frame IsClippedToBounds="True"
BorderColor="{Binding BorderColor}"
BackgroundColor="{Binding IconBackgroundColor}"
CornerRadius="38"
HeightRequest="60"
WidthRequest="60"
HorizontalOptions="Center"
VerticalOptions="Center">
<Image Source="{Binding IconImageSource}"
Margin="-20"
WidthRequest="100"
HeightRequest="100"
Aspect="AspectFill" />
</Frame>
<Label Grid.Column="1"
Text="{Binding CardTitle}"
FontAttributes="Bold"
FontSize="Large"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Start" />
<BoxView Grid.Row="1"
Grid.ColumnSpan="2"
BackgroundColor="{Binding BorderColor}"
HeightRequest="2"
HorizontalOptions="Fill" />
<Label Grid.Row="2"
Grid.ColumnSpan="2"
Text="{Binding CardDescription}"
VerticalTextAlignment="Start"
VerticalOptions="Fill"
HorizontalOptions="Fill" />
</Grid>
</Frame>
</ControlTemplate>
</Application.Resources>
</Application>
If I want to use this ControlTemplate
in Page1.xaml
. We can use it directly.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:ControlTemplateDemos.Controls"
mc:Ignorable="d"
x:Class="ControlTemplateDemos.Views.Page1">
<ContentPage.Content>
<StackLayout>
<controls:CardView BorderColor="DarkGray"
CardTitle="John Doe"
CardDescription="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla elit dolor, convallis non interdum."
IconBackgroundColor="SlateGray"
IconImageSource="user.png"
ControlTemplate="{StaticResource CardViewControlTemplate}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Here is running GIF.
Upvotes: 2