views:

57

answers:

1

Hello Everyone,

In the example below, the DataTemplate only gets applied to the first and second list item, the third and fourth are completely ignored.

<ListBox>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding}"></Button>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <sys:String>One</sys:String>
    <sys:String>Two</sys:String>
    <ListBoxItem>Three</ListBoxItem>
    <ListBoxItem>Four</ListBoxItem>
</ListBox>

My question is why?

If I look at the output window, I see the following error: “ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container type; Type='ListBoxItem'.

So I get why my templates are not being applied, but why does WPF gets all nasty with me when I explicitly use ListBoxItems objects on my list items? I mean, WPF is implicitly hosting ALL items on a ListBoxItems object so why can’t WPF just thank me for doing some of the work that it is supposed to do rather than throwing the error? :)

Thank you.

+1  A: 

It sounds more like a warning than error -- just filling you in on why your declared ItemTemplate and ListBoxItems aren't going to work together.

edit

In response to your comment, consider the following:

    <ListBox>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Button Content="{Binding}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
        <ListBox.Items>
            <System:String>One</System:String>
            <System:String>Two</System:String>
            <ListBoxItem Background="Red">Three</ListBoxItem>
            <ListBoxItem>
                <ListBoxItem.Template>
                    <ControlTemplate>
                        <Button Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" 
                                Background="Blue"
                                Foreground="White"
                                />
                    </ControlTemplate>
                </ListBoxItem.Template>
                <ListBoxItem.Content>
                    Four
                </ListBoxItem.Content>
            </ListBoxItem>
        </ListBox.Items>
    </ListBox>

Think of the ItemTemplate as defining a way to display the item type. For items "One" and "Two", which are strings, the ItemTemplate defines how to display that and wraps the result in a ListBoxItem.

If, however, an item is already a ListBoxItem

  1. This is not an item that the ItemTemplate can necessarily deal with because an ItemTemplate is a DataTemplate, and
  2. The ListBoxItem can define its own properties, style, and template.

So, if you are explicitly creating ListBoxItems, I think it is better that WPF respect the ability to customize the styling of that item, rather than overriding it all with the ItemTemplate.

That's the beauty of using ItemTemplates -- you can use them, mix, match, and mangle them, usually without really having to worry about ListBoxItem. The only time I've ever had to deal with ListBoxItem directly is when I create a style for it -- declaring one as an item explicitly is probably a rare case at best.

Jay
I agree that is more of a warning than an error but still, I was mostly curious to try to understand why explicitly using ListBoxItem would have the side effect of my DataTemplate being ignored when behind the scenes, WPF add ListBoxItems to my entries anyway.
Dot Net Luchador
@Dot I added an updated response.
Jay