Reputation: 87
I have a ListView whose ItemsSource I set programmatically in the code behind. I used to only have one Template but now I want to use multiple templates and select the template according to the item I add to the ListView.
This is the XAML Code I have:
<Page.Resources>
<local:TemplateSelector x:Key="myTemplateSelector" TemplateA="{StaticResource TemplateA}" TemplateB="{StaticResource TemplateB}" />
<!-- TemplateA and TemplateB -->
</Page.Resources>
<ListView
x:Name="MasterListView"
Grid.Row="1"
ItemContainerTransitions="{x:Null}"
ItemTemplateSelector="{StaticResource myTemplateSelector}"
IsItemClickEnabled="True"
ItemClick="MasterListView_ItemClick"/>
I then set the ItemSource of the ListView and this is my TemplateSelector:
public class TemplateSelector : DataTemplateSelector
{
public DataTemplate TemplateA { get; set; }
public DataTemplate TemplateB { get; set; }
public new DataTemplate SelectTemplate(object item, DependencyObject container)
{
return TemplateA;
}
}
However, this does not work. Instead of my desired template I always get the same text for every item: AppName.ViewModels.ViewModel1 (the type of the data I want to show).
In the past when I only had one itemtemplate I used this in the xaml and it worked:
<ListView
x:Name="MasterListView"
Grid.Row="1"
ItemContainerTransitions="{x:Null}"
ItemTemplate="{StaticResource TemplateA}"
IsItemClickEnabled="True"
ItemClick="MasterListView_ItemClick"/>
How can I get the ItemTemplateSelector to work? I placed breakpoints there but it does not even get called.
Upvotes: 1
Views: 1693
Reputation:
public override DataTemplate SelectTemplate(object item, DependencyObject container)
instead of
public new DataTemplate SelectTemplate(object item, DependencyObject container)
EDIT, due to access modifier, this is the signature for 4.5.2 (note it's public):
#region Assembly PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\PresentationFramework.dll
#endregion
namespace System.Windows.Controls
{
//
// Summary:
// Provides a way to choose a System.Windows.DataTemplate based on the data object
// and the data-bound element.
public class DataTemplateSelector
{
//
// Summary:
// Initializes a new instance of the System.Windows.Controls.DataTemplateSelector
// class.
public DataTemplateSelector();
//
// Summary:
// When overridden in a derived class, returns a System.Windows.DataTemplate based
// on custom logic.
//
// Parameters:
// item:
// The data object for which to select the template.
//
// container:
// The data-bound object.
//
// Returns:
// Returns a System.Windows.DataTemplate or null. The default value is null.
public virtual DataTemplate SelectTemplate(object item, DependencyObject container);
}
}
Upvotes: 1
Reputation: 15758
As it is described in the Remarks of DataTemplateSelector.SelectTemplate(Object, DependencyObject) method:
App code typically doesn't call SelectTemplate methods; the methods exists so that the infrastructure can call it while choosing the correct templates based on using a DataTemplateSelector instance from a property value such as ItemsControl.ItemsTemplateSelector. To provide a specific template in a derived class, override the SelectTemplateCore(Object, DependencyObject) method.
So we should use
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
instead of
public new DataTemplate SelectTemplate(object item, DependencyObject container)
Upvotes: 2