loading...
Web Atoms

How to write Templates in Xamarin.Forms with TypeScript?

akashkava profile image Akash Kava ・2 min read

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 by:

Web Atoms

TSX instead of Xaml, TypeScript instead of C#, Hot reload Xamarin.Forms published App, use VS Code for Xamarin.Forms Development.... "Web Atoms" is an advanced MVVM framework to write cross platform applications in HTML5 and Xamarin.Forms.

Discussion

markdown guide