Bring element forward (Z Index) in Silverlight/WPF

Rich picture Rich · Mar 10, 2009 · Viewed 69.5k times · Source

All the documentation and examples I'm finding online for setting Z-Index to bring an element forward in Silverlight are using a Canvas element as a container.

My items are Border elements inside of an ItemsControl container in a DataTemplate. I'm using the MouseEnter and MouseLeave events to trigger an animation on the ScaleTransform.ScaleX and ScaleTransform.ScaleY so they grow when hovered. As they're resized and occupying the same space as other items in the container(s), the most recently added items are overlapping the older items (as opposed to the currently resizing item). Is there a CLEAN way to bring the current item forward in code where I trigger my animation so that they overlap all other items when they're resized?

Answer

user127111 picture user127111 · Jun 22, 2009

I've had to deal with this.

Say you have an ItemsControl with an ItemTemplate set to an instance of a custom control. Within that control you do Canvas.SetZIndex(this, 99). It won't work, because "this" is not the immediate child of the ItemsControl's ItemsPanel. The ItemsControl creates a ContentPresenter for each item, drops that into the ItemsPanel, and renders the ItemTemplate within the ContentPresenter.

So, if you want to change the ZIndex within your control, you have to find its ContentPresenter, and change the ZIndex on that. One way is...

        public static T FindVisualParent<T>( this DependencyObject obj )
        where T : DependencyObject
    {
        DependencyObject parent = VisualTreeHelper.GetParent( obj );
        while ( parent != null )
        {
            T typed = parent as T;
            if ( typed != null )
            {
                return typed;
            }
            parent = VisualTreeHelper.GetParent( parent );
        }
        return null;
    }
                ContentPresenter foo = this.FindVisualParent<ContentPresenter>();
            Canvas.SetZIndex( foo, 99 );