I did a little WPF programming a long time ago, but I am just returning to xaml with UWP, but I think this should work and cannot figure out why. Basically I want to use an ItemsControl (because I just want to list some data, I don't want selection) instead of a ListView control. Here are my resources:
<Page.Resources>
    <DataTemplate x:Key="SentMessageDataTemplate">
        <TextBlock Text="Sent" />
    </DataTemplate>
    <DataTemplate x:Key="ReceivedMessageDataTemplate">
        <TextBlock Text="Recieved" />
    </DataTemplate>
    <services:MessageDataTemplateSelector x:Key="MessageDataTemplateSelector" ReceivedTemplate="{StaticResource ReceivedMessageDataTemplate}" SentTemplate="{StaticResource SentMessageDataTemplate}"></services:MessageDataTemplateSelector>
</Page.Resources>
Here is my ItemsControl:
<ItemsControl ItemsSource="{Binding Messages}" ItemTemplateSelector="{StaticResource MessageDataTemplateSelector}" />
Here is my DataTemplateSelector:
public class MessageDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate SentTemplate
    {
        get;
        set;
    }
    public DataTemplate ReceivedTemplate
    {
        get;
        set;
    }
    protected override DataTemplate SelectTemplateCore(object item)
    {
        var message = item as MessageViewModel;
        if (message == null)
        {
            return this.SentTemplate;
        }
        return message.Sent ? this.SentTemplate : this.ReceivedTemplate;
    }
}
Instead of displaying either of my templates it just displays my ViewModel type name (so basically ToString).
However if I switch it from ItemsControl to ListView, it works fine.
Any suggestions?
Use this override instead:
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
This is the one that gets called, not the one without the 2nd parameter.
Interesting -- ListView and GridView both invoke the template selector; plain ItemsControl or ListBox do not.
Overriding the other SelectTemplateCore method in the template selector helps, e.g.:
protected override DataTemplate SelectTemplateCore(object item)
{
    var message = item as MessageViewModel;
    if (message == null)
    {
        return SentTemplate;
    }
    return message.Sent ? SentTemplate : ReceivedTemplate;
}
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
    return SelectTemplateCore(item);
}
The latter method is called in all cases; the first isn't called for ItemsControl items. This page provides an explanation of sorts:
If your
ItemsControl.ItemsPanelis anItemsStackPanelorItemsWrapGrid, provide an override for theSelectTemplateCore(Object)method. If theItemsPanelis a different panel, such asVirtualizingStackPanelorWrapGrid, provide an override for theSelectTemplateCore(Object, DependencyObject)method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With