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:
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:
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:
Download the demo project here: Customized SelectedItem (Demo) Be sure to change the file extension from .DOC to .ZIP and then decompress it.
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!
Hi Josh,
Could you explain why you use StackPanel.Visibility and not just Visibility in the Setter of the DataTrigger?
Thanks,
David.
Visibility doesn’t work but Grid.Visibility does, why did you use StackPanel?
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
We can use inheritance from Selector ItemContainerStyle dependency property and set in it new custom style value for item. Is it more natural?
RredCat,
I would have to see an example of what you have in mind before I could agree or disagree.
Josh
😦 I can’t add sample here, therefore I loaded sample in to http://upload.com.ua/filelink.php?type=link&id=899949640
Sorry, Incorrect linc
http://upload.com.ua/get/899949640
RredCat,
That’s a nice alternative solution. I’m not sure which one I like better. 🙂
Thanks,
Josh
If need change only DataTemplate, your way is better.
If need “rich customize” my way..
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?
Hello, Josh. Maby that is more natural
<–
–>
code is hidden 😦
To arkhivania:
Use symbols code < and > (& l t ; and & g t ; – remove space).
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.
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
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. 😉
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.
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.
Good work. I have your example.