ItemTemplateSelector

RadChat control exposes an ItemTemplateSelector property which you can use to apply different templates to each chat item depending on a specific condition.

Any change on the appearance of the chat items depends on the ChatItemTemplateSelector and the containing templates and referenced Styles. The default selector includes separate templates for the incoming and outgoing messages, as well as for the first, middle and last messages - this is needed in order to achieve the "balloon" look & feel of the messages.

You can also create a custom ChatItemTemplateSelector to conditionally apply different messages styles depending on any of the used chat item properties.

Let's, for example, have the following ChatItem class with a custom MessageCategory property to distinguish important messages:

public enum MessageCategory
{
    Important,
    Normal
}
public class SimpleChatItem
{
    public Author Author { get; set; }
    public string Text { get; set; }
    public MessageCategory Category { get; set; }
}

Add a few sample Items to the Chat's ItemsSource:

this.Items = new ObservableCollection<SimpleChatItem>();

// Simulate async data loading
Device.StartTimer(TimeSpan.FromMilliseconds(500), () =>
{
    this.Items.Add(new SimpleChatItem { Author = this.Bot, Text = "Hi.", Category = MessageCategory.Normal });
    this.Items.Add(new SimpleChatItem { Author = this.Bot, Text = "Please check our new privacy policy here:...", Category = MessageCategory.Important });
    return false;
});

You would need to supply an ItemsConverter as you're using custom items as demonstrated inside MVVM Support topic.

public class SimpleChatItemConverter : IChatItemConverter
{
    public ChatItem ConvertToChatItem(object dataItem, ChatItemConverterContext context)
    {
        SimpleChatItem item = (SimpleChatItem)dataItem;
        TextMessage textMessage = new TextMessage()
        {
            Data = dataItem,
            Author = item.Author,
            Text = item.Text
        };
        return textMessage;
    }
    public object ConvertToDataItem(object message, ChatItemConverterContext context)
    {
        ViewModel vm = (ViewModel)context.Chat.BindingContext;
        return new SimpleChatItem { Author = vm.Me, Text = (string)message, Category=MessageCategory.Normal };
    }
}

Create a CustomChatItemTemplateSelector class that derives from the ChatItemTemplateSelector:

public class CustomChatItemTemplateSelector : ChatItemTemplateSelector
{
    public DataTemplate ImportantMessageTemplate { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        ChatItem chatItem = item as ChatItem;
        var myItem = chatItem?.Data as SimpleChatItem;
        if (myItem != null && myItem.Category == MessageCategory.Important)
        {
            return this.ImportantMessageTemplate;
        }
        return base.OnSelectTemplate(item, container);
    }
}

Create the needed XAML resources:

<ResourceDictionary>
    <local:SimpleChatItemConverter x:Key="SimpleChatItemConverter" />

    <Style x:Key="MessageImageStyle" TargetType="Image">
        <Setter Property="Source" Value="{Binding Author.Avatar}" />
        <Setter Property="WidthRequest" Value="30" />
        <Setter Property="HeightRequest" Value="30" />
    </Style>

    <Style x:Key="IncomingMessageImageStyle" TargetType="Image" BasedOn="{StaticResource MessageImageStyle}">
        <Setter Property="HorizontalOptions" Value="Start" />
        <Setter Property="Margin" Value="10, 0, 0, 0" />
    </Style>

    <DataTemplate x:Key="ImportantMessageTemplate">
        <Grid Margin="0, 2, 0, 10">
            <Image Style="{StaticResource IncomingMessageImageStyle}" />
            <telerikPrimitives:RadBorder CornerRadius="0, 7, 7, 7"
                                    Margin="45, 0, 50, 0"
                                    HorizontalOptions="Start"
                                    BackgroundColor="#FF0000">
                <StackLayout Orientation="Horizontal" Margin="20, 0, 20, 0">
                    <Label Text="! " FontAttributes="Bold" FontSize="Medium" />
                    <Label Text="{Binding Text}" FontSize="Medium" />
                </StackLayout>
            </telerikPrimitives:RadBorder>
        </Grid>
    </DataTemplate>
    <local:CustomChatItemTemplateSelector x:Key="CustomChatItemTemplateSelector"
        ImportantMessageTemplate="{StaticResource ImportantMessageTemplate}" />
</ResourceDictionary>

Finally, set it to the Chat's ItemTemplateSelector property:

<telerikConversationalUI:RadChat x:Name="chat"                                    
                    Author="{Binding Me}"
                    ItemsSource="{Binding Items}" 
                    ItemConverter="{StaticResource SimpleChatItemConverter}"                          
                    ItemTemplateSelector="{StaticResource CustomChatItemTemplateSelector}">
    <telerikConversationalUI:RadChat.BindingContext>
        <local:ViewModel />
    </telerikConversationalUI:RadChat.BindingContext>
</telerikConversationalUI:RadChat>

Figure 1: RadChat with ItemTemplateSelector

ItemTemplateSelector

See Also

In this article
Not finding the help you need? Improve this article