Question

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. ;)

Was it helpful?

Solution 2

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

OTHER TIPS

I was having the same problem with a Universal Application and simply setting the ElementName was not sufficient. Make sure that your Interactivity and your VisualStateManager tags are at the same hierarchical level. That fixed the problem in my case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top