Search code examples
wpflistboxitemtemplate

ListBox ItemTemplateSelector doesn't work


I am attempting to use an ItemTemplateSelector on a WPF ListBox and have looked at several examples online. Seemed simple enough but I cannot get it to work. I am hoping that someone can tell me where I've gone wrong:

Fist, I have an DataTemplateSelector class defined as follows:

Public Class DocketDataTemplateSelector
    Inherits DataTemplateSelector

    Public Overrides Function SelectTemplate(ByVal item As Object, ByVal container As DependencyObject) As DataTemplate
        Return DataDocketHeaderTemplate
    End Function

    Private _DataDocketHeaderTemplate As DataTemplate
    Public Property DataDocketHeaderTemplate() As DataTemplate
        Get
            Return _DataDocketHeaderTemplate
        End Get
        Set(ByVal value As DataTemplate)
            _DataDocketHeaderTemplate = value
        End Set
    End Property

    Private _DataDocketDataTemplate As DataTemplate
    Public Property DataDocketDataTemplate() As DataTemplate
        Get
            Return _DataDocketDataTemplate
        End Get
        Set(ByVal value As DataTemplate)
            _DataDocketDataTemplate = value
        End Set
    End Property
End Class

Very simple - just returns the DataDocketHeaderTemplate datatemplate for the time being until I can get it to work.

I then have my user control with the following as its resource definition:

<UserControl.Resources>
    <DataTemplate x:Key="docketHeaderTemplate">
        <TextBlock Text="Header Row Test" Background="Yellow"/>
    </DataTemplate>

    <DataTemplate x:Key="docketDataTemplate">
        <TextBlock Text="Data Row Test" Background="Green"/>
    </DataTemplate>

    <local:DocketDataTemplateSelector DataDocketHeaderTemplate="{StaticResource docketHeaderTemplate}" DataDocketDataTemplate="{StaticResource docketDataTemplate}" x:Key="myDataTemplateSelector"/>
</UserControl.Resources>

The ListBox in the user control is simply defined like this:

    <ListBox ItemsSource="{Binding TestData}" ItemTemplateSelector="{StaticResource myDataTemplateSelector}"/>

Then finally, my TestData list is defined in my bound viewmodel like so:

Private _listTestData As ObservableCollection(Of String) = Nothing
    Public Property TestData As ObservableCollection(Of String)
        Get
            If _listTestData Is Nothing Then
                _listTestData = New ObservableCollection(Of String)
                _listTestData.Add("Row 1")
                _listTestData.Add("Row 2")
                _listTestData.Add("Row 3")
            End If
            Return _listTestData
        End Get
        Set(ByVal value As ObservableCollection(Of String))
            _listTestData = value
            NotifyPropertyChanged("TestData")
        End Set
    End Property

Now, I expect I would see a list of 3 rows in my listbox all saying 'Header Row Test' (since my datatemplateselector is always returning DataDocketHeaderTemplate). But instead I see my core data of Row 1 Row 2 Row 3

This seems to indicate that my overriding datatemplateselector is not being hit (indeed if I set a breakpoint in DocketDataTemplateSelector, at no time do I see it being hit). Where am I going wrong with this?

Thanks


Solution

  • Sorry i can not post this as comment, i haven't got enough score.

    I just tried your example code (my first VB project) and guess what, it works as expected: three times "Header Row Test" on yellow background. I've put the ListBox in a Grid in the UserControl, then put the UserControl in a Grid in a Window, then set the DataContext of the UserControl to a ViewModel object with your TestData property.

    Something must be wrong that is not demonstrated by your example code, maybe you can provide more info.