Customizing the selected item in a ListBox

This blog post demonstrates how to make the selected ListBoxItem in a ListBox display differently than unselected items.  We will see how to add an extra Button to the selected item, but you can add whatever you want by using the technique shown below.  This is what the demo app looks like when you run it and select an item:

Customized SelectedItem (screenshot)

The trick is to set the ListBox’s ItemTemplate to a DataTemplate which knows when to expose the extra visuals for the selected item(s).  Here’s an example of a template which knows how to do that:

 Customized SelectedItem (template)

That DataTemplate creates two Grids.  The outer Grid has two rows: the top row is for the normal item content, and the bottom row hosts the selected item’s extra content.  The inner Grid is in the bottom row.  That inner Grid has a Style which knows when to hide itself (i.e. when the ListBoxItem is not selected).

Here’s a ListBox which consumes that template:

 Customized SelectedItem (ListBox)

Download the demo project here: Customized SelectedItem (Demo) Be sure to change the file extension from .DOC to .ZIP and then decompress it.

20 Responses to Customizing the selected item in a ListBox

  1. Patrick says:

    Hi Josh,

    Perfect! That’s exactly what I was looking for!

    I found another approach on the internet that used a completely separate control template for each of the states, but that resulted in a massive amount of replicated XAML and I thought that was simply ridiculous. I figured there had to be a better way. This method is so elegant!

    Thanks so much!

  2. David says:

    Hi Josh,

    Could you explain why you use StackPanel.Visibility and not just Visibility in the Setter of the DataTrigger?

    Thanks,

    David.

  3. Corrado Cavalli says:

    Visibility doesn’t work but Grid.Visibility does, why did you use StackPanel?

  4. Josh Smith says:

    That was an oversight. The XAML initially used a StackPanel instead of a Grid to hold the Button. I changed it to a Grid but forgot to change the type which qualifies the Visibility property. Oops. The screenshot and demo project have been updated. Now it uses Grid.Visibility just for the sake of consistency.

    Josh

  5. RredCat says:

    We can use inheritance from Selector ItemContainerStyle dependency property and set in it new custom style value for item. Is it more natural?

  6. Josh Smith says:

    RredCat,

    I would have to see an example of what you have in mind before I could agree or disagree.

    Josh

  7. RredCat says:

    😦 I can’t add sample here, therefore I loaded sample in to http://upload.com.ua/filelink.php?type=link&id=899949640

  8. RredCat says:

    Sorry, Incorrect linc
    http://upload.com.ua/get/899949640

  9. Josh Smith says:

    RredCat,

    That’s a nice alternative solution. I’m not sure which one I like better. 🙂

    Thanks,
    Josh

  10. RredCat says:

    If need change only DataTemplate, your way is better.
    If need “rich customize” my way..

  11. jturpin says:

    I am currently working on a more elaborate version of this that is definitely pushing my limites of WPF knowledge… elaborate in the sense that there is actually an extra state added to the selected state – one in which even *more* info is displayed after a certain amount of time has elapsed and the selection hasn’t changed. Even crazier is that the designers want animations between all of these states (both scale and opacity transforms). So it goes something like: change selection->animate to selected state (slightly different than non-selected state)->…time elapses…->animate to super selected state (several new items fade into view) -> user moves selection -> quick animation back to normal state -> animate to new selected item. Rinse and repeat. This is a tough one… I am currently working off of a hacked up version of ListControl, however I am thinking about abonding this and rolling my own completely custom Panel… thoughts?

  12. arkhivania says:

    Hello, Josh. Maby that is more natural

    <–

    –>

  13. arkhivania says:

    code is hidden 😦

  14. RredCat says:

    To arkhivania:
    Use symbols code < and > (& l t ; and & g t ; – remove space).

  15. arkhivania says:

    So. I think more naturally use two DateTemplates:
    SmallTemplate and FullTemplate… and inside ListBox use ItemContainerStyle property where for ListBoxItem set ContentTemplate and one trigger for IsSelected property of ListBoxItem. It’s very important NOT set ItemsContentTemplate and use Setter for ContentTemplate. Sorry for my english.

  16. Josh Smith says:

    Arkhivania,

    I agree that there is a certain “cleanness” to your approach. On the other hand, I, personally, would probably avoid it because it introduces a lot of duplicated XAML into the application. If the SmallTemplate and FullTemplate are essentially the same set of visuals but FullTemplate simply adds an element here or there, then you are faced with a maintenance problem. By consolidating them both into one template you can avoid the duplication entirely.

    Then again, if the two templates are very different then it probably makes sense to use your approach and split it into two templates.

    Josh

  17. Jan Kucera says:

    Hello, nice to see how did you wrote it, I had to figure out how to implement this task a couple days before, for ComboBox.

    I ended up by deriving from ComboBox and adding SelectedItemTemplate dependency property.

    However, ComboBox already has a mechanism for this, at least I think so, and this is the SelectionBoxItemTemplate property. It seems it’s always filled by the ItemTemplate and, unfortunately, it has private setter. Do you know why or if it is somehow possible to provide separate template for ComboBox in a more easy fashion?

    Jan

    PS: On the opposite side of duplicating XAML is creating the controls (in your case butons) and holding in memory for every item in the list, although not needed. But I have no idea if this is that much costy. 😉

  18. Mark W says:

    I was curious if there is some way to change the selection color for the items in a listbox. I can’t seem to locate anything relative to the selection color for the items which appears to be based on the OS Theme. Is there a way to override that?

    Great work on the wpf articles and posts Josh, you’ve been a major help in my foray into wpf.

  19. Bjoern says:

    Interesting article. I am trying to call a method in my code-behind file where I use the template. How can I define the method that is called when the button is pressed?

    Thanks.

  20. Good work. I have your example.