ListView data binding with mutiple data templates in Xamarin Forms
This article describes the ListView data binding with multiple data/item templates in Xamarin Forms. Since this feature is being implemented in Xamarin forms, it works in all the platforms windows, android & ios.
To use multiple data templates for a ListView, use DataTemplateSelector for selecting
the appropriate data template based on a type or a condition at runtime.
Note: To make use of DataTemplateSelector, ensure to update the Xamarin forms package to latest stable version (should be
>=2.1).
Let’s create a simple chat user interface and distinguish the messages as incoming
and outgoing as in below screenshot.

Create a Xamarin Forms project and update the Xamarin.forms package to latest stable
version.
Since ListView allows you to display a list of data using cells, create a custom
incoming message cell and outgoing message cell.
Incoming Message XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ListViewBinding.UserControls.InBoundViewCell">
<StackLayout>
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.15*"></ColumnDefinition>
<ColumnDefinition Width="0.85*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.Column="1" BackgroundColor="#ffffff"
Padding="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" Text="{Binding MessageText}" Margin="10,10,10,0"
FontSize="22" TextColor="#7799CC"></Label>
</Grid>
</Grid>
</StackLayout>
</ViewCell>
Outgoing Message XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ListViewBinding.UserControls.OutBoundViewCell">
<StackLayout>
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.85*"></ColumnDefinition>
<ColumnDefinition Width="0.15*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Grid.Row="1" Grid.Column="0" BackgroundColor="#7799CC">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" Margin="10,10,10,0" Text="{Binding
MessageText}" FontSize="22">
</Label>
</Grid>
</Grid>
</StackLayout>
</ViewCell>
Create a class that inherits from DataTemplateSelector and override the OnSelectTemplate
method to select a particular DataTemplate
public class MessageTemplateSelector : DataTemplateSelector
{
private readonly DataTemplate inBoundDataTemplate;
private readonly DataTemplate outBoundDataTemplate;
public MessageTemplateSelector()
{
this.inBoundDataTemplate = new DataTemplate(typeof(InBoundViewCell));
this.outBoundDataTemplate = new DataTemplate(typeof(OutBoundViewCell));
}
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
var messageModel = item as Message;
return messageModel != null && messageModel.MessageType == "INBOUND" ? this.inBoundDataTemplate : this.outBoundDataTemplate;
}
}
Create a ListView and apply the DataTemplateSelector by creating a static resource
with in the ResourceDictionary.
<ContentPage.Resources>
<ResourceDictionary>
<userControls:MessageTemplateSelector x:Key="MessageTemplateSelector"></userControls:MessageTemplateSelector>
</ResourceDictionary>
</ContentPage.Resources>
<ListView
x:Name="lstMessages"
HorizontalOptions="Fill"
VerticalOptions="Fill"
SeparatorVisibility="None"
ItemTemplate="{StaticResource MessageTemplateSelector}">
</ListView>
Finally, bind the ItemsSource to ListView as below.
var messages = new List<Message>();
messages.Add(new Message { MessageId = 1, MessageText = "Hello! First InBound Message, right side data item", MessageType = "INBOUND" });
messages.Add(new Message { MessageId = 2, MessageText = "Hello! First Outbound Message, left side data item", MessageType = "OUTBOUND" });
this.Messages = new ObservableCollection<Message>(messages);
lstMessages.ItemsSource = Messages;
Download the working sample
By Siva Jagan Dhulipalla Popularity (4275 Views)