0
votes

I'm trying to create a XAML template in Xamarin Forms that I can reference from multiple screens. The template has a header, a summary, and can receive touch input. In the attached wireframe, there would be a model backing the three blocks of data. I've read through the docs at https://developer.xamarin.com/guides/xamarin-forms/templates/control-templates/template-binding/, but at this point I feel like I'm missing an important concept. I thought I would just need to create a ContentView template and somehow make the Labels inside bindable to an object at runtime via .BindingContext. What am I missing?

Content Page

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Namespace.SettingsPage"
             Title ="Settings">
  <ContentPage.Resources>
    <ResourceDictionary>
        <ControlTemplate x:Key="SettingTemplate">
            <StackLayout>
                <Label
                    x:Name="Header"
                    Text="{TemplateBinding Parent.Header}" />
                <Label 
                    x:Name="Summary"
                    Text="{TemplateBinding Parent.Summary}"/>
                </StackLayout>                    
        </ControlTemplate>
    </ResourceDictionary>
  </ContentPage.Resources>
  <ContentPage.Content>      
    <StackLayout>      
        <StackLayout>
            <ContentView x:Name="alerts" ControlTemplate="{StaticResource SettingTemplate}"></ContentView>
            <ContentView x:Name="recipients" ControlTemplate="{StaticResource SettingTemplate}"></ContentView>
            <ContentView x:Name="log" ControlTemplate="{StaticResource SettingTemplate}"></ContentView>
        </StackLayout>
    </StackLayout>
  </ContentPage.Content>
</ContentPage>

Code Behind

using Xamarin.Forms;

namespace Namespace.Settings
{
    public partial class SettingsPage : ContentPage
    {
        protected SettingsViewModel viewModel;

        public SettingsPage(AlertInfo info)
        { 
            InitializeComponent();
            BindingContext = viewModel = new SettingsViewModel(info, this);

            // Bind individual models here. AlertSummary VM has logic to pull out
            // header and summary fiels.
            this.alerts.BindingContext = new AlertSummaryViewModel(info, Summary.ALERTS, this);
            this.recipients.BindingContext = new AlertSummaryViewModel(info, Summary.RECIPIENTS, this);
        }       
    }
}

Wireframe

1
The question is not clear. What are you trying to do exactly that doesn't work? Example, here is my page, here is control I want to add based on that template and I don't see that. Also please provide all necessary xml and code behind to reproduceYuri S
Thanks Yuri, I added xaml and code behind.David
To reproduce missing definitions: SettingsViewModel, AlertInfo, AlertSummaryViewModel, Summary.ALERTS.After you provide those please tell me what doesn't work? From the image I see that all data is populated or it is desired image?Yuri S
This is a wireframe of a desired outcome. I'm not looking to debug so much as looking for guidance on whether this is possible with Xamarin Forms, and if so, where to look for examples.David
It is possible and example you provided in your link in the question. If you do everything right you will get it done. If you have a problem then please provide a code to quickly recreate and help you with you problem. I still don't even know what you are getting on screen and what is the problemYuri S

1 Answers

1
votes

Here is the starting point.

    public partial class ControlTemplateTest : ContentPage
    {
        public static readonly BindableProperty HeaderTextProperty =
            BindableProperty.Create("HeaderText", typeof(string), typeof(ControlTemplateTest), "Alerts");
        public static readonly BindableProperty SummaryTextProperty =
          BindableProperty.Create("SummaryText", typeof(string), typeof(ControlTemplateTest), "Three alerts set");

        public string HeaderText
        {
            get { return (string)GetValue(HeaderTextProperty); }
        }

        public string SummaryText
        {
            get { return (string)GetValue(SummaryTextProperty); }
        }

        public ControlTemplateTest()
        {
            InitializeComponent();
        }
    }
}

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"
             x:Class="ButtonRendererDemo.ControlTemplateTest">
  <ContentPage.Resources>
    <ResourceDictionary>
      <ControlTemplate x:Key="SettingTemplate">
        <StackLayout BackgroundColor="#DCF394" >
          <Label FontSize="48" TextColor="Black" Text="{TemplateBinding Parent.Parent.HeaderText}" />
          <Label Text="{TemplateBinding Parent.Parent.SummaryText}"/>
        </StackLayout>
      </ControlTemplate>
    </ResourceDictionary>
  </ContentPage.Resources>

  <ContentPage.Content>
    <StackLayout BackgroundColor="White" VerticalOptions="FillAndExpand" Spacing="0,40" Padding="0,40">
      <ContentView  x:Name="alerts" VerticalOptions="FillAndExpand" ControlTemplate="{StaticResource SettingTemplate}"></ContentView>
      <ContentView x:Name="recipients" VerticalOptions="FillAndExpand" ControlTemplate="{StaticResource SettingTemplate}"></ContentView>
      <ContentView x:Name="log" VerticalOptions="FillAndExpand" ControlTemplate="{StaticResource SettingTemplate}"></ContentView>
    </StackLayout>
  </ContentPage.Content>
</ContentPage>

enter image description here