4

I have a custom control on which I'd like to add a mouse-over behavior to bring the object in its entirety to the top of the z-order then have it drop back into position when mouse is over a different object on the canvas.

I have the following XAML, in which the color animates, the ZIndex of the rectangle within the control animates (obscuring the ellipse), but I can't get the entire control to bring itself to the front of all other controls in the parent canvas. The troublesome part of the XAML is shown with a blank line before and after below.

<Style TargetType="local:CustomControl1">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:CustomControl1">
                <Grid x:Name="PartLayoutRoot">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="MouseOver">
                                <Storyboard>

                                    <Int32AnimationUsingKeyFrames 
                                            Storyboard.Target="{Binding RelativeSource={RelativeSource TemplatedParent} }"
                                            Storyboard.TargetProperty="(Canvas.ZIndex)">
                                        <DiscreteInt32KeyFrame KeyTime="0" Value="99" />
                                    </Int32AnimationUsingKeyFrames>

                                    <Int32AnimationUsingKeyFrames 
                                            Storyboard.TargetName="Rect"
                                            Storyboard.TargetProperty="(Canvas.ZIndex)">
                                        <DiscreteInt32KeyFrame KeyTime="0" Value="99" />
                                    </Int32AnimationUsingKeyFrames>
                                    <ColorAnimation To="Red" 
                                        Storyboard.TargetName="Rect" 
                                        Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
                                        Duration="0:0:1" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>

                    <Rectangle x:Name="Rect" Fill="Blue" Height="40" Width="40" />
                    <Ellipse Fill="Green" Height="30" Width="30" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Basically I can animate ZIndex intra-control but not inter-control. I've read this post which implies I should be able to do this - note in my case, the template parent is the instance of the custom control, not an element in a list so the solution in that scenario doesn't seem to apply. The error I get follows

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:(no path); DataItem=null; target element is 'Int32AnimationUsingKeyFrames' (HashCode=58939632); target property is 'Target' (type 'DependencyObject')

Elsewhere I've read this doesn't work because what comes back from a Binding isn't a dependency object. I have this all working in code now, but looking for a more elegant XAML solution.

Jim O'Neil
  • 23,344
  • 7
  • 42
  • 67
  • +1 this would be cool to know, might be worth trying to climb the tree via Ancestor if it's SL5, I'll take a stab at it when I get some free time since this would be a nifty effect to have in the old toolbox. – Chris W. Apr 11 '14 at 14:51

1 Answers1

0

The solution here would be to change the ZIndex not in the VisualState of the template, but in a trigger of the style.

<Style TargetType="local:CustomControl1">
    <Setter Property="Template">
        ...
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="(Canvas.ZIndex)" Value="99"/>
        </Trigger>
    </Style.Triggers>
</Style>

Hope this helps!