views:

30

answers:

1

I have a ListBox that uses a WrapPanel for its ItemsPanel, a custom ItemTemplate, and a custom ItemContainerStyle. The ItemContainerStyle's template contains a selection box that shows up when an item is selected. The graphics designer would like this selection box to overlap sibling items in the ListBox like it's an overlay.

The first thing I tried was setting the Canvas.ZIndex property of the ItemContainer in the Selected state. That did not seem to have an effect. Then I read that list items might be wrapped inside of a ContentPresenter, so I created an attached property that changes the ZIndex of an item's parent, but then I found out Silverlight storyboards don't let you animate custom attached properties.

Does anyone know of a technique we can use to achieve the effect we desire?

A: 

I found a solution. Basically, I created an attached property that sets up an event handler on any Selector (including ListBox) for when its selection changes. When it changes, the code iterates through all of the item containers, adjusting the Canvas.ZIndex based on whether the container represents the selected item:

public static readonly DependencyProperty SetZIndexOnSelectionProperty = DependencyProperty.RegisterAttached(
    "SetZIndexOnSelection", typeof(bool), typeof(FrameworkUtils), 
    new PropertyMetadata(zIndexSettingChanged));

public static bool GetSetZIndexOnSelection(DependencyObject obj)
{
    return (bool)obj.GetValue(SetZIndexOnSelectionProperty);
}

public static void SetSetZIndexOnSelection(
    DependencyObject obj, bool value)
{
    obj.SetValue(SetZIndexOnSelectionProperty, value);
}

private static void zIndexSettingChanged(
    DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
    if (obj is Selector)
    {
        var selector = obj as Selector;
        selector.SelectionChanged += (s, e) =>
        {
            if (selector.SelectedItem != null)
            {
                foreach (var pair in selector.GetItemsAndContainers())
                {
                    pair.Value.SetValue(
                        Canvas.ZIndexProperty, 
                        (pair.Key == selector.SelectedItem) ? 1 : 0);
                }
            }
        };
    }
}
Jacob