How to write Templates in Xamarin.Forms with TypeScript?
Akash Kava
Posted on March 2, 2020
List View
Same as in XAML, you can create DataTemplate
easily in TSX as shown below, syntax is not very different then that of Xaml.
import Bind from "@web-atoms/core/dist/core/Bind";
import XNode from "@web-atoms/core/dist/core/XNode";
import { AtomXFControl } from "@web-atoms/core/dist/xf/controls/AtomXFControl";
import XF from "@web-atoms/xf-controls/dist/clr/XF";
import AtomXFContentPage from "@web-atoms/xf-controls/dist/pages/AtomXFContentPage";
import ListViewModel from "./ListViewModel";
export default class List extends AtomXFContentPage {
public viewModel: ListViewModel;
public create() {
this.viewModel = this.resolve(ListViewModel);
this.render(
<XF.ContentPage title="List Sample">
<XF.ListView itemsSource={Bind.oneWay(() => this.viewModel.movies.value)}>
<XF.ListView.itemTemplate>
<XF.DataTemplate>
<XF.ViewCell>
<XF.Label text={Bind.oneWay((x) => x.data.name)}/>
</XF.ViewCell>
</XF.DataTemplate>
</XF.ListView.itemTemplate>
</XF.ListView>
</XF.ContentPage>
);
}
}
Same as that of Xaml, you can define DataTemplate
with a ViewCell
or any element that is derived from Cell
Template Selector
Writing template selector requires little different syntax.
this.render(<XF.ContentPage title="List with Template Selector">
<XF.ListView itemsSource={Bind.oneWay(() => this.viewModel.movies.value)}>
<WA.AtomTemplateSelector.templateSelector>
<WA.AtomTemplateSelector selector={(d: IMovie) => /horror/i.test(d.genre)
? 1 : 0}>
{/* Template 0 */}
<XF.DataTemplate>
<XF.TextCell
text={Bind.oneWay((x) => x.data.name)}
textColor="black"
/>
</XF.DataTemplate>
{/* Template 1 */}
<XF.DataTemplate>
<XF.TextCell
text={Bind.oneWay((x) => x.data.name)}
textColor="red"
/>
</XF.DataTemplate>
</WA.AtomTemplateSelector>
</WA.AtomTemplateSelector.templateSelector>
</XF.ListView>
</XF.ContentPage>);
As you can see, WA.AtomTemplateSelector
is a placeholder element, which will simply set template based on some condition.
selector
condition evaluates and returns an index of templates enclosed within AtomTemplateSelector
.
Collection View
In collection view, you can write templates without cells, same as in Xaml.
<XF.CollectionView
itemsSource={Bind.oneWay(() => this.viewModel.movies.value)}>
<XF.CollectionView.itemTemplate>
<XF.DataTemplate>
<XF.Label text={Bind.oneWay((x) => x.data.name)}/>
</XF.DataTemplate>
</XF.CollectionView.itemTemplate>
</XF.CollectionView>
How does it work?
XF.DataTemplate
translates to Xamarin.Forms.DataTemplate
and it uses constructor with factory to create elements only when needed.
How to create control template?
Creating control template is exactly same with little difference in CLR Xamarin binding syntax.
Following example displays, how to change ControlTemplate
of AtomField
in form.
<WA.AtomForm.fieldStyle>
<XF.ControlTemplate>
<XF.Grid>
<XF.Grid.rowDefinitions>
<XF.RowDefinition height="Auto"/>
<XF.RowDefinition/>
<XF.RowDefinition height="Auto"/>
</XF.Grid.rowDefinitions>
<XF.Label
text={X.TemplateBinding("Label")}
textColor="Green"
/>
<XF.ContentPresenter
{ ... XF.Grid.row(1)}
/>
</XF.Grid>
</XF.ControlTemplate>
</WA.AtomForm.fieldStyle>
Binding
of Xamarin.Forms is actually replaced with X.Binding
and X.TemplateBinding
.
In above example, XF.ControlTemplate
refers to ControlTemplate
of Xamarin.Forms. Templates are optimized to be reused and there is no performance lag even when they are written in TypeScript.
Interoperability
Web Atoms allows you to use, both JavaScript as well as Xamarin Bindings on TemplateBinding
as well as Binding
. However, little care must be taken based on source object. To bind properties of classes written in C# you must use X.Binding
and X.TemplateBinding
respectively. To bind objects created in JavaScript, you must use Bind.oneWay/twoWays
syntax.
Posted on March 2, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.