C# – WPF ListBox using ItemsSource and ItemTemplate

bindingclistboxwpf

I'm confused as to how bindings are resolved when I have both an ItemsSource and an ItemTemplate in a WPF ListBox.

I have an ObservableCollection<int> called ListOfIndexes. For each index, I want to look up its record in a database table. I hope to do that in the IndexToObjectDescriptionConverter.

<ListBox ItemsSource="{Binding ListOfIndexes}" 
         ItemTemplate="{Binding Converter={StaticResource IndexToObjectDescriptionConverter}}" />

But a breakpoint in the converter is telling me that the value being read in by the ItemTemplate binding is of the window itself — i.e., the DataContext of the ItemsSource and ItemsTemplate is the same.

Pardon a bit of candidness, but this seems DUMB. The entire point of the ItemTemplate is to render each element within the ItemsSource, so I guess I figured that the DataContext of the ItemTemplate would be the individual element being rendered.

So, that said, how do I tell the ItemTemplate that it should worry about the individual elements represented by the ItemsSource and not use the entire window's DataContext?

Best Answer

You need to use a data template for the ItemTemplate. This is then applied to each item in the list

MSDN docs are here: http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemtemplate(v=vs.110).aspx

The issue her is about data context scope. When you bind any property on the ListBox, it will use the data context of the ListBox - hence why that data context is being passed to the converter. If you set a data template inside the ItemTemplate, it will apply that template to each item in the list. I guess based on the simple code you've provided you would need to have the converter inside the data template:

<ListBox ItemsSource="{Binding ListOfIndexes}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <ContentControl Content="{Binding Converter={StaticResource IndexToObjectDescriptionConverter}}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

In this case, the ContentControl will be rendered for each item, with that item as it's data context.

Related Topic