Alan2
Alan2

Reputation: 24562

Can I set up a template in Xamarin Forms for Xaml that's repetitive?

I use the same XAML many times in my application with two minor differences which are the value of the Text and Selected that I pass in:

<ViewCell Tapped="selectValue" >
   <Grid VerticalOptions="CenterAndExpand" Padding="20,0" >
      <local:StyledLabel Text="{Binding [1].Name}" HorizontalOptions="StartAndExpand" />
      <local:StyledLabel IsVisible="{Binding [1].IsSelected}" TextColor="Gray" HorizontalOptions="End" Text="✓" />
   </Grid>
</ViewCell>

Does Xamarin forms have any template feature where I could for example shorten this to something like:

<local:SwitchViewCell Text="{Binding [1].Name}" Selected="{Binding [1].IsSelected}" />

Here's what I have so far:

<?xml version="1.0" encoding="utf-8" ?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
          xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
          mlns:local="clr-namespace:Japanese;assembly=Japanese"
          x:Class="Japanese.SwitchViewCell""
          Tapped="selectValue" >
   <Grid VerticalOptions="CenterAndExpand" Padding="20,0" >
      <local:StyledLabel Text="{Binding Text, Source={x:Reference this}}" HorizontalOptions="StartAndExpand" />
      <local:StyledLabel IsVisible="{Binding IsVisible, Source={x:Reference this}}" TextColor="Gray" HorizontalOptions="End" Text="✓" />
   </Grid>
</ViewCell>

With this code behind right now:

namespace Japanese.Templates
{
    public partial class SwitchViewCell : ViewCell
    {
        public SwitchViewCell()
        {
            InitializeComponent();
        }

        public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(SwitchViewCell));
        public static readonly BindableProperty IsVisibleProperty = BindableProperty.Create(nameof(IsVisible), typeof(bool), typeof(SwitchViewCell));

        public string Text
        {
            get
            {
                return (string)GetValue(TextProperty);
            }
            set
            {
                SetValue(TextProperty, value);
            }
        }

        public bool IsVisible
        {
            get
            {
                return (bool)GetValue(IsVisibleProperty);
            }
            set
            {
                SetValue(IsVisibleProperty, value);
            }
        }


    }
}

I'm not sure if this is 100% the way to go but when I try to implement this I get the message:

 EventHandler "selectValue" not found in type "Japanese.Templates.SwitchViewCell" (Japanese)

Upvotes: 0

Views: 576

Answers (2)

MilanG
MilanG

Reputation: 2604

ListView Cell:

For the ListView cell, you can define the ViewCell layout of ListView item. Ex. PersonCell.xaml

<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
          x:Class="DataTemplates.PersonCell">
     <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.3*" />
            <ColumnDefinition Width="0.3*" />
            <ColumnDefinition Width="0.4*" />
        </Grid.ColumnDefinitions>
        <Label Text="{Binding FirstName}" />
        <Label Grid.Column="1" Text="{Binding LastName}" />
        <Label Grid.Column="2" Text="{Binding Email}" />
    </Grid>
</ViewCell>

Then you can use this into ListView's DataTemplate as:

<ListView ItemSource="{Binding PersonList}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <local:PersonCell />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

This way ListView resuses the cell design for each item.

Reusable View:

You can also make a reusable view which can be simply included in your page. Ex. MyCustomView.xaml:

<Grid xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Xam.Control.MyCustomView"> 
    <StackLayout>
        <Label Text="Hello"/>
        <Label Text="How Are You?"/>
    </StackLayout>
</Grid>

Page:

<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms" 
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
xmlns:customView="clr-namespace:Xam.Control;assembly=Xam"
x:Class="Xam.View.HomePage">

Here, notice that you have to include the namespace and assembly where your custom view resides.

And then in this page, simply add it like:

<customView:MyCustomView />

Upvotes: 1

Gerald Versluis
Gerald Versluis

Reputation: 33993

Sure, just put it in a separate XAML file and define a the bindable properties that you need and map the values onto the controls in your custom control. In fact, the latter is not absolutely needed but is nicer to make it completely reusable.

If you just want to reuse it in your project and always data bind it to the same fields, you can leave it as-is, as the BindingContext will be inherited.

To get you started, you might want to have a look at a blog post of mine about this: https://blog.verslu.is/xamarin/xamarin-forms-xamarin/reusable-custom-usercontrols-with-bindableproperty/

Upvotes: 0

Related Questions