0
votes

What in the world is wrong with this ListBox? It is showing items as plain strings, not using the template I have provided:

<ListBox>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Ellipse Width="20" Height="20" Fill="LightBlue" />
                <TextBlock Text="{TemplateBinding Content}" Foreground="Red" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.Items>
        <ListBoxItem>html</ListBoxItem>
        <ListBoxItem>head</ListBoxItem>
        <ListBoxItem>body</ListBoxItem>
        <ListBoxItem>table</ListBoxItem>
        <ListBoxItem>tr</ListBoxItem>
        <ListBoxItem>td</ListBoxItem>
    </ListBox.Items>
</ListBox>
2
I can only assume that it is because you are using Items directly. What if you try to bind ItemsSource property?stukselbax
@stukselbax: Thanks. For some strange reason that appears to work. Any insight on why is that so? What if I have a static list of items that I want to hardcode into XAML?dotNET

2 Answers

3
votes

From the Remarks section in the ItemTemplate MSDN page:

When you set an ItemTemplate on an ItemsControl, the UI is generated as follows (using the ListBox as an example):

1.During content generation, the ItemsPanel initiates a request for the ItemContainerGenerator to create a container for each data item. For ListBox, the container is a ListBoxItem. The generator calls back into the ItemsControl to prepare the container.

2.Part of the preparation involves the copying of the ItemTemplate of the ListBox to be the ContentTemplate of the ListBoxItem.

3.Similar to all ContentControl types, the ControlTemplate of a ListBoxItem contains a ContentPresenter. When the template is applied, it creates a ContentPresenter whose ContentTemplate is bound to the ContentTemplate of the ListBoxItem.

4.Finally, the ContentPresenter applies that ContentTemplate to itself, and that creates the UI.

These steps are apparently not executed when you create ListBoxItem instances directly in XAML. It is however not strictly necessary to bind the ItemSource property. You may also directly set items like this:

<ListBox xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Ellipse Width="20" Height="20" Fill="LightBlue" />
                <TextBlock Text="{TemplateBinding Content}" Foreground="Red" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.Items>
        <sys:String>html</sys:String>
        <sys:String>head</sys:String>
        <sys:String>body</sys:String>
        <sys:String>table</sys:String>
        <sys:String>tr</sys:String>
        <sys:String>td</sys:String>
    </ListBox.Items>
</ListBox>
1
votes
public class MyViewModel
{
    public List<String> Items
    {
        get { return new List<String> { "html", "head", "body","table","tr","td" }; }
    }
}

//This can be done in the Loaded event of the page:

DataContext = new MyViewModel();

Your XAML

<ListBox Margin="20" ItemsSource="{Binding Items}">
    <ListBox.ItemTemplate>
        <DataTemplate>
             <Ellipse Width="20" Height="20" Fill="LightBlue" />
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>