Skip to content
Jean-Philippe Bruyère edited this page Nov 1, 2021 · 4 revisions

Templates split the internals of a control and its graphical representation. Control's internals are programed in c# and their templates in IML, the declarative interface language of CROW.

TemplatedControl may be used for controls without children. For your control to accept a single child, derive TemplatedContainer and for handling multiple children, use the TemplatedGroup as base class.

The following graph will guide you to the right ancestor for your needs:

Once a new templated control is created, it must provide a template written in IML. One possibility is declaring it inline with the <Tempate> tag:

<MyTemplatedControl Caption="my templated control">
  <Template>
    <Label Text="{./Caption}" Background="{./Background}"/>
  </Template>
</MyTemplatedControl>

All the properties of the TemplatedControl are bindable with the special syntax (one dot and a slash followed by the templated control's property name): "{./Property}"

Templates could also be defined in a separate file without the enclosing <Tempate> tag. For our previous example, we could create a file MyTemplatedControl.template which would contains:

<Label Text="{./Caption}" Background="{./Background}"/>

Then you use the Template property of the templated control:

<MyTemplatedControl Template="MyTemplatedControl.template" Caption="my templated control"/>

If both Template property and inline template are present, the second has priority.

Default Template

Each templated control should provide a default template, if not, it must implement the inlined <Template> tag, or set a template explicitly for each occurence of the templated widget with the Template path attribute of the TemplatedControl.

To provide a default template, it must be an embedded ressource with its LogicalName = #fullTypeName.template (case sensitive). For exemple, the logical name of the default template for the Crow.Button class is Crow.Button.template. Then you may declare Buttons in IML that will automatically load that template.

It is also possible to declare the template with Styling, it will have priority on the default one, but declaring an inline template in IML or using the Template property when declaring the control will override it.

exemple of a template set with styling.
MyTemplatedControl {
  Template = "#MyTemplate.temp";
}

TemplatedContainer

All templated containers must provide inside their template a container widget named 'Content' to handle child addition.

exemple
<TemplatedContainer>
  <Template>
    <Border>
      <Container Name="Content"/>
    </Border>
  </Template>
</Border>

TemplatedGroup

Templated groups must provide in their template's tree a widget derived from the Group class named ItemsContainer, it is mandatory.

<TemplatedGroup>
  <Template>
    <VerticalStack Name="ItemsContainer"/>
  </Template>
</Border>

In addition to their normal templates, they introduce Items Templates used to display children. Their may be choosen at runtime among several ones depending on the type of data it is used for or on a member value of the data item.

Item templates may be set through the ItemTemplate property of the TemplatedGroup or defined inlined enclosed in <ItemTemplate> tags.

exemple of inline item template
<TemplatedGroup>
  <ItemTemplate>
    <Label NameText="{datasourceMember}"/>
  </ItemTemplate>
</Border>

The ItemTemplate tag accept 3 facultative attributes:

  • Path: pointing to an IML file containing a single item template without enclosing <ItemTemplate> tag. If Path attribute is set, the <ItemTemplate>tag must be a self-closing tag.
  • DataType: Usage is affected by the value of the DataTest property of the TemplatedGroup.
    • DataTest="TypeOf"=> Fully qualified type name that trigger the selection of this item template to display the data element.
    • DataTest=member name of the data item=> value for that property that will trigger the selection of this template.
  • Data: Used only for hierarchical datas, name of the member for fetching children of that node when expand is triggered. If Data is defined, ItemTemplate must contains an element derived from the Group class named ItemsContainer.

If DataType is not specified for an Item template, this one will be used as default. If no item template is defined at all, crow include a default one (#Crow.DefaultItem.template).

ItemTemplate files may be composed of a single item template with or without enclosing <ItemTemplate> tag, or may include multiple templates each imperatively enclosed in that tag.

Further readings

Check the tutorials for examples of creating new templated controls.

Clone this wiki locally