views:

68

answers:

3

I want to reproduce a ListBox used in the Windows Phone 7 calendar. When the list does not have focus, only the selected item is shown. When the list gets focused, it smootly grows (vertically) to show all items.

My limited Silverlight and Blend talent is failing me. I thought I could achieve all this via the ItemContainerStyle, but the FocusStates group is for each item, not the list, right?

What approach should I take?

+1  A: 

You are correct that there is no specific focus state in the ListBox itself (except for the invalid state which is no use to you). You can only change focus states on individual items using templates.

Option 1

When you want to make a change based on states not already in a control you are better off making a custom user control. In this case you would then catch the focus states with 2 ControlStoryboardAction behaviours which use 2 storyboards to transition the control to/from focused. I would probably use a second (non-list) control for the unfocused state and bind it to the selected item of the ListBox.

Option 2

You could subclass the existing control (ListBox in this instance), but that is more work as you need to provide default templates. The you could add Focus/Unfocused states.

The choice depends on your long term aims, but I would go with a simple custom user control. Probably take less than an hour to make.

Hope this helps.

Enough already
A: 

I have used Alex Yakhnin's implemenation, which simply resizes the ListBox to a single item's height, the selected item being shown, other items are simply above and below, but not in the viewport.

Martin Plante
A: 

No, no, no people!! No resizing, no custom controls or worse, subclassing needed! Just create a style for ListBoxItem that that sets its Visibility property to 'Collapsed' and its 'IsEnabled' property to 'false' when the the ListBoxItem's IsSelected is false and the ListBox itself doesn't have focus. (Best way to do that is with a MultiTrigger.) Finally, set the listbox to auto-size to its contents. Done and done! And it's pure XAML too!

We use this technique to quickly 'filter' lists and even TreeViews quite effectively except we bind the visibility to an IsFiltered property in our ViewModel.

Best part, since you're not binding to an ObservableCollection that you're constantly adding and removing things from, any properties which are view-only (i.e. IsExpanded for instance) are exactly as you left them when the items are shown again, all without having to track them in the ViewModel! It's purely UI. All 'View'.

Did I mention it's pure XAML??? Oh... I did. Just making sure you know it's PURE XAML!!!

And again... make sure to set 'IsEnabled' to false when you hide the ListBoxItem (use a trigger or binding to do it for you) or your keyboard navigation will not work!

MarqueIV