About a month ago, I saw two unrelated questions where an ItemsControl was not behaving correctly when clicking on an item: Events weren’t being raised, items weren’t getting selected; chaos ensued.  In both cases, the developer was adding an items container to the data template.  (As a refresher, ListBoxItem, ListViewItem, and TreeViewItem are examples of item containers.)  They were doing something like the following:

 

        <Grid>

            <Grid.Resources>

                <src:ItemsForSale x:Key="Data"/>

            </Grid.Resources>

            <ListBox ItemsSource="{StaticResource Data}">

                <ListBox.ItemTemplate>

                  <DataTemplate>

                        <ListBoxItem Padding="3,8,3,8" MouseDoubleClick="ListBoxItem_MouseDoubleClick" >

                            <TextBlock Text="{Binding Path=Description}"/>

                        </ListBoxItem>

                    </DataTemplate>

 

                </ListBox.ItemTemplate>

 

            </ListBox>

        </Grid>

 

When the correct way to implement the ListBox is something like the following:

 

        <Grid>

            <Grid.Resources>

                <src:ItemsForSale x:Key="Data"/>

            </Grid.Resources>

            <ListBox ItemsSource="{StaticResource Data}">

                <ListBox.ItemContainerStyle>

                    <Style  TargetType="ListBoxItem">

                        <Setter Property="Padding" Value="3,8,3,8"/>

                        <EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/>

                    </Style>

                </ListBox.ItemContainerStyle>

                <ListBox.ItemTemplate>

                    <DataTemplate>

                        <TextBlock Text="{Binding Path=Description}"/>

                    </DataTemplate>

 

                </ListBox.ItemTemplate>

 

            </ListBox>

        </Grid>

 

In the second example, properties and events for item containers are set on a style, and the data template contains only elements that go in each item container.  You see, when the ItemsControl is bound to a data source, an items container is implicitly created for each item in the source, so in the first example above two ListBoxItem objects are made for each item: the one that is implicitly created and the one in the data template. In the second example, only the implicitly created ListBoxItem is present, and the Padding and event handler from the style is applied to each ListBoxItem.

 

For full disclosure, I must say that when I experimented with the first example, I got inconsistent results.  Sometimes I couldn’t select an item but I could get the double click event to occur and sometimes I could select the item but not raise the event.  So be forewarned: Don’t put item containers in data templates; only weird things happen if you do!