Search code examples
c#wpfxamlblendvisualstatemanager

GoToStateAction refusing to change state


I'm trying to make a little marker rectangle appear on the side of the following user control using a VisualStateManager, but my DataTrigger / EventTrigger (tried both) seem to refuse to change the UserControl's state. Any ideas? I'm currently using Blend for VS 2013 to design the control.

XAML:

<UserControl x:Class="Docular.Client.Windows.UI.SidebarElement"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" 
         xmlns:dms="clr-namespace:Docular.Client.Windows.UI"
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
         xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
         Width="110" Height="110"
         DataContext="{Binding RelativeSource={RelativeSource Self}}"
         x:Name="element" 
         Style="{DynamicResource SidebarElementStyle}">
<UserControl.Resources>
    <Style x:Key="SidebarElementStyle" TargetType="{x:Type UserControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type UserControl}">
                    <Grid x:Name="grid">
                        <i:Interaction.Triggers>
                            <ei:DataTrigger Binding="{Binding IsMouseOver, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type dms:SidebarElement}}}" Value="True">
                                <ei:GoToStateAction x:Name="MouseOverAction" StateName="MouseOver" TargetObject="{Binding Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type dms:SidebarElement}}}"/>
                            </ei:DataTrigger>
                        </i:Interaction.Triggers>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition GeneratedDuration="0:0:0.25"/>
                                </VisualStateGroup.Transitions>
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="MouseOver">
                                    <Storyboard>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Marker">
                                            <EasingDoubleKeyFrame KeyTime="0" Value="0.75"/>
                                        </DoubleAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground)" Storyboard.TargetName="ContentLabel">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource MediumLightBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Selected">
                                    <Storyboard>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Marker">
                                            <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                                        </DoubleAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground)" Storyboard.TargetName="ContentLabel">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BrightLightBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="5*"/>
                            <RowDefinition Height="40*"/>
                            <RowDefinition Height="15*"/>
                            <RowDefinition Height="5*"/>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="5*"/>
                            <ColumnDefinition Width="25*"/>
                            <ColumnDefinition Width="{Binding CenterColumnWidth, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/>
                            <ColumnDefinition Width="25*"/>
                            <ColumnDefinition Width="5*"/>
                        </Grid.ColumnDefinitions>

                        <Rectangle x:Name="Marker"
                                   Fill="{DynamicResource HighlightBrush}"
                                   Grid.Row="1" Grid.RowSpan="2"
                                   Opacity="0"/>
                        <ContentControl x:Name="IconDisplay" 
                                        Content="{Binding Path=Icon, ElementName=element}" 
                                        Grid.Column="2" Grid.Row="1"/>
                        <Label x:Name="ContentLabel" Content="{TemplateBinding Content}" 
                               Style="{DynamicResource LabelStyleRegularDarkLight}"
                               Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="2"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

Code-Behind:

public partial class SidebarElement : UserControl
{
    public static DependencyProperty CenterColumnWidthProperty = DependencyProperty.Register("CenterColumnWidth", typeof(GridLength), typeof(SidebarElement), new PropertyMetadata(new GridLength(40, GridUnitType.Star)));

    public static DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(Path), typeof(SidebarElement));

    [Bindable(true, BindingDirection.TwoWay)]
    public GridLength CenterColumnWidth
    {
        get
        {
            return (GridLength)(this.GetValue(CenterColumnWidthProperty) ?? default(GridLength));
        }
        set
        {
            this.SetValue(CenterColumnWidthProperty, value);
        }
    }

    [Bindable(true, BindingDirection.TwoWay)]
    public Path Icon
    {
        get
        {
            return (Path)this.GetValue(IconProperty);
        }
        set
        {
            this.SetValue(IconProperty, value);
        }
    }

    public SidebarElement()
    {
        InitializeComponent();
    }
}

I'm not all-new to XAML but to me it seems like I still got a lot left to learn. ;)


Solution

  • Wonderful, setting the TargetObject in the EventTrigger to {Binding ElementName=grid} fixed it!