Implementing IDataTemplate
If you need more control over your DataTemplate you can do this by creating a class which implements the IDataTemplate-interface. With this interface you can create your own DataTemplate not only respecting the DataType of your data, but also its properties or whatever you like.
To use this interface you must implement the following two members in your class:
  • public bool Match(object data) { ... } you need to check in this method if the provided data matches your IDataTemplate or not. You need to return true if the data matches, otherwise false.
  • public IControl Build(object param) { ... } In this method you need to build and return the control which represents your data.

Basic Example

Below is a very basic sample implementation of the IDataTemplate-interface:
1
// remember to import the needed namespace
2
// using Avalonia.Controls.Templates;
3
​
4
public class MyDataTemplate : IDataTemplate
5
{
6
public IControl Build(object param)
7
{
8
// build the control to display
9
return new TextBlock() { Text = (string)param };
10
}
11
​
12
public bool Match(object data)
13
{
14
// Check if we can accept the provided data
15
return data is string;
16
}
17
}
Copied!
You can now use the class MyDataTemplate in your view like this:
1
<!-- remember to add the needed prefix in your view -->
2
<!-- xmlns:dataTemplates="using:MyApp.DataTemplates" -->
3
​
4
<ContentControl Content="{Binding MyContent}">
5
<ContentControl.ContentTemplate>
6
<dataTemplates:MyDataTemplate />
7
</ContentControl.ContentTemplate>
8
</ContentControl>
Copied!

Advanced Example

Sometimes you may want to display a different Control for different states of your ViewModel. Let's assume you have a Property which is an enum called ShapeType, defined like this:
1
public enum ShapeType
2
{
3
RedCircle,
4
RedSquare,
5
BlueCircle,
6
BlueSquare
7
}
Copied!
We use this enum in our ViewModel as a property:
1
// In our sample we use ReactiveUI but you don't need to do it.
2
​
3
private ShapeType _ShapeType;
4
​
5
/// <summary>
6
/// Gets or sets the shape type to display
7
/// </summary>
8
public ShapeType ShapeType
9
{
10
get { return _ShapeType; }
11
set { this.RaiseAndSetIfChanged(ref _ShapeType, value); }
12
}
Copied!
In our view we want to show a red circle if the user selects ShapeType.RedCircle and we want to show a blue square if the user selects ShapeType.BlueSquare. To achieve this will create a class called ShapesTemplateSelector, where have a Dictionary which stores the shape representations we want to look up.
1
// remember to import the needed namespace
2
// using Avalonia.Controls.Templates;
3
​
4
public class ShapesTemplateSelector : IDataTemplate
5
{
6
// This Dictionary should store our shapes. We mark this as [Content], so we can directly add elements to it later.
7
[Content]
8
public Dictionary<string, IDataTemplate> AvailableTemplates { get; } = new Dictionary<string, IDataTemplate>();
9
​
10
// Build the DataTemplate here
11
public IControl Build(object param)
12
{
13
var key = param.ToString(); // Our Keys in the dictionary are strings, so we call .ToString() to get the key to look up
14
if(key is null) // If the key is null, we throw an ArgumentNullException
15
{
16
throw new ArgumentNullException(nameof(param));
17
}
18
return AvailableTemplates[key].Build(param); // finally we look up the provided key and let the System build the DataTemplate for us
19
}
20
​
21
// Check if we can accept the provided data
22
public bool Match(object data)
23
{
24
// Our Keys in the dictionary are strings, so we call .ToString() to get the key to look up
25
var key = data.ToString();
26
27
return data is ShapesEnum // the provided data needs to be our enum type
28
&& !string.IsNullOrEmpty(key) // and the key must not be null or empty
29
&& AvailableTemplates.ContainsKey(key); // and the key must be found in our Dictionary
30
}
31
}
Copied!
Now we will setup the ShapesTemplateSelector in the DataTemplates-section of our App.axaml:
1
<!-- remember to add the needed prefix in your view -->
2
<!-- xmlns:dataTemplates="using:MyApp.DataTemplates" -->
3
<!-- xmlns:model="using:MyApp.Model" -->
4
​
5
<Application.DataTemplates>
6
<dataTemplates:ShapesTemplateSelector>
7
<DataTemplate x:Key="RedCircle" DataType="model:ShapesEnum">
8
<Ellipse Width="50" Height="50" Fill="Red" Stroke="DarkRed" StrokeThickness="2" />
9
</DataTemplate>
10
<DataTemplate x:Key="BlueCircle" DataType="model:ShapesEnum">
11
<Ellipse Width="50" Height="50" Fill="Blue" Stroke="DarkBlue" StrokeThickness="2" />
12
</DataTemplate>
13
<DataTemplate x:Key="RedSquare" DataType="model:ShapesEnum">
14
<Rectangle Width="50" Height="50" Fill="Red" Stroke="DarkRed" StrokeThickness="2" />
15
</DataTemplate>
16
<DataTemplate x:Key="BlueSquare" DataType="model:ShapesEnum">
17
<Rectangle Width="50" Height="50" Fill="Blue" Stroke="DarkBlue" StrokeThickness="2" />
18
</DataTemplate>
19
</dataTemplates:ShapesTemplateSelector>
20
</Application.DataTemplates>
Copied!
Now we can will create a ComboBox which the user can use to select a ShapeType:
1
<!-- remember to add the needed prefix in your view -->
2
<!-- xmlns:model="using:MyApp.Model" -->
3
​
4
<StackPanel>
5
​
6
<TextBlock Text="Select a Shape" />
7
​
8
<ComboBox SelectedIndex="0">
9
<model:ShapeType>RedCircle</model:ShapeType>
10
<model:ShapeType>BlueCircle</model:ShapeType>
11
<model:ShapeType>RedSquare</model:ShapeType>
12
<model:ShapeType>BlueSquare</model:ShapeType>
13
</ComboBox>
14
</StackPanel>
Copied!
Our final result looks like this:
Export as PDF
Copy link
Edit on GitHub