WPF Templates are useful for defining common themes and styles. They can also be used to extend the functionality of controls. Following is an example of a ListBoxItem template, which makes individual items in a listbox in-place editable (provided the listbox contains strings only). To achieve this effect, the standard ListBoxItem template is modified as follows (note, to achieve similar effect with Win32 ListBox would require significant amount of procedural code):

  • Instead of just having a ContentPresenter (to show the content), the modified template has a ContentPresenter and a TextBox, the latter overlaying the first. Initially the TextBox is in Collapsed state (invisible and not occupying any space).
  • The template includes a property trigger based on IsSelected property. The trigger modifies the setting of the TextBox defined above to make it visible.
  • The trigger also databinds the content of the TextBox to the listbox item's content using the RelativeSource source reference.

The downside of this approach is that the logical tree now contains an additional control (TextBox) for each item in the listbox item, which if the listbox is bound to a large collection could have performance implications.

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Xml Data Binding" FontSize="20"
    >
  <StackPanel Orientation="Horizontal">
    <StackPanel.Resources>
      <Style x:Key="{x:Type ListBoxItem}" TargetType="{x:Type ListBoxItem}">
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
              <Grid>
                <ContentPresenter />
                <TextBox Name="EditableText" Visibility="Collapsed"/>
              </Grid>
              <ControlTemplate.Triggers>
                <Trigger Property="IsSelected" Value="true">
                  <Setter TargetName="EditableText" Property="Visibility" Value="Visible" />
                  <Setter TargetName="EditableText" Property="Text" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"/>
                </Trigger>
              </ControlTemplate.Triggers>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>
    </StackPanel.Resources>
    <ListBox Width="100" Height="155">
      <ListBoxItem>Item 1</ListBoxItem>
      <ListBoxItem>Item 2</ListBoxItem>
      <ListBoxItem>Item 3</ListBoxItem>
      <ListBoxItem>Item 4</ListBoxItem>
      <ListBoxItem>Item 5</ListBoxItem>
      <ListBoxItem>Item 6</ListBoxItem>
      <ListBoxItem>Item 7</ListBoxItem>
      <ListBoxItem>Item 8</ListBoxItem>
      <ListBoxItem>Item 9</ListBoxItem>
      <ListBoxItem>Item 10</ListBoxItem>
    </ListBox>
    <ListBox Width="100" Height="155">
      <ListBoxItem>Item 1</ListBoxItem>
      <ListBoxItem>Item 2</ListBoxItem>
      <ListBoxItem>Item 3</ListBoxItem>
      <ListBoxItem>Item 4</ListBoxItem>
      <ListBoxItem>Item 5</ListBoxItem>
      <ListBoxItem>Item 6</ListBoxItem>
      <ListBoxItem>Item 7</ListBoxItem>
      <ListBoxItem>Item 8</ListBoxItem>
      <ListBoxItem>Item 9</ListBoxItem>
      <ListBoxItem>Item 10</ListBoxItem>
    </ListBox>
  </StackPanel>
</Page>