Reputation: 503
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?
Upvotes: 12
Views: 7875
Reputation: 221
Here is what the documentation says:
Remarks
If your ItemsControl.ItemsPanel is an ItemsStackPanel or ItemsWrapGrid, provide an override for the SelectTemplateCore(Object) method. If the ItemsPanel is a different panel, such as VirtualizingStackPanel or WrapGrid, provide an override for the SelectTemplateCore(Object, DependencyObject) method.
Upvotes: 1
Reputation: 5498
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.ItemsPanel
is anItemsStackPanel
orItemsWrapGrid
, provide an override for theSelectTemplateCore(Object)
method. If theItemsPanel
is a different panel, such asVirtualizingStackPanel
orWrapGrid
, provide an override for theSelectTemplateCore(Object, DependencyObject)
method.
Upvotes: 5
Reputation: 7163
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.
Upvotes: 16
Reputation: 120
Maybe you should use <TextBlock Text="{Binding Sent}" />
You don't bind anything in your Template.
Upvotes: 0