iKnowNothing
iKnowNothing

Reputation: 979

External ControlTemplate in Xamarin.Forms without template layout property on page

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

Answers (2)

iKnowNothing
iKnowNothing

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

Leon Lu
Leon Lu

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.

enter image description here

Upvotes: 2

Related Questions