Editable ListBox using template


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>

Comments (5)

  1. Neeta says:

    Can we do the same thing for Silverlight 2 ? if yes how ?

  2. Stéphanie says:

    Hello,

    Thanks, it’s very useful for me. But I have a problem when I copy the style of ListBoxItem :

    When I write a text which is one of the ListBoxItem’s value, and then, when I make the scrolling down or up, it’s not link to this text.

    For example I’ve got this list 1,2,3,4,5,6. And the listbox is default in the value "1".

    If I write in the TextBox "3" and I make the scrolling down it displays "2" instead of "4".

    I tried to change the property "Mode" to "TwoWay", but it doesn’t work :

    <Setter TargetName="EditableText" Property="Text" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content, Mode=TwoWay}"/>

    Have you got any solution ?

    (Sorry for my bad english, I hope you’ll understand me)

  3. SundaramR says:

    Hi I have found that it is working great. I am working on a project using this. But i have a trouble now. I need to add an image in front of each listboxitem. If i do so i am not able to edit in this manner because content value is not string this time. Please help me ASAP.

  4. SundaramR says:

    Hi or is there a better way to restrict the content value so that for some particular listboxitem which has string alone as content i can keep this editable and for the rest of the items which has both image & string I can track down the string & edit that one alone. Please reply ASAP.

    Thanks in Advance….

  5. Ritesh says:

    Hi,

    I have the similart kind of req as SundaramR is having. Kindly let me know if anybody can provide me something for that.

    Thanks in advance.

Skip to main content