0
votes

I've been trying to get a WPF multi datatrigger to work on triggering a storyboard animation on a customized ToggleButton based of this control http://marcangers.com/animated-switch-togglebutton-style-in-wpf/ . The toggle button is an extension of a regular WPF ToggleButton with a custom attribute of Status which will either show as Modified or Unmodified. My MultiDataTrigger is triggering on whether the togglebutton IsChecked and the status is either modified or unmodified. The problem is, the storyboards aren't triggering at all. When I have the storyboard animations in a regular trigger it works just fine. Here's the custom toggle button.

CustomToggleButton.xaml

<ToggleButton x:Class="DPC9600CustomControlLibrary.CustomToggleButton"
         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" 
         xmlns:local="clr-namespace:ControlLibrary"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
    <ToggleButton.Resources>
        <ResourceDictionary Source="Themes/Styles_CustomToggleButton.xaml"/>
    </ToggleButton.Resources>
    <ToggleButton.Style>
        <Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource CustomToggleButton}"/>
    </ToggleButton.Style>
</ToggleButton>

CustomToggleButton.xaml.cs

public partial class CustomToggleButton : ToggleButton
{
    public static readonly DependencyProperty StatusProperty =
        DependencyProperty.Register("Status", typeof(ConfigurationValueStatus), typeof(CustomToggleButton));



    public ConfigurationValueStatus Status
    {
        get { return (ConfigurationValueStatus) GetValue(StatusProperty); }
        set { SetValue(StatusProperty, value); }
    }

    public CustomToggleButton()
    {
        InitializeComponent();
    }
}

And here's my multidata triggers in Styles_CustomToggleButton.xaml

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="True"/>
        <Condition Binding="{Binding Status,ElementName=Myself}" Value="Unmodified"/>
    </MultiDataTrigger.Conditions>
    <MultiDataTrigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation Storyboard.TargetProperty="Background.Color" To="#FF377EC1" Duration="0:0:0.2" />
                <ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#FF377EC1" Duration="0:0:0.2" />
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ellipse">
                    <SplineDoubleKeyFrame KeyTime="0" Value="0"/>
                    <SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="15" KeySpline="0, 1, 0.6, 1"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </BeginStoryboard>
    </MultiDataTrigger.EnterActions>
    <MultiDataTrigger.ExitActions>
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation Storyboard.TargetProperty="Background.Color" To="#FAFAFB" Duration="0:0:0.2" />
                <ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#EAEAEB" Duration="0:0:0.2" />
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ellipse">
                    <SplineDoubleKeyFrame KeyTime="0" Value="15"/>
                    <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0" KeySpline="0, 0.5, 0.5, 1"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </BeginStoryboard>
    </MultiDataTrigger.ExitActions>
</MultiDataTrigger>
<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="True"/>
        <Condition Binding="{Binding Status,ElementName=Myself}" Value="Modified"/>
    </MultiDataTrigger.Conditions>
    <MultiDataTrigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation Storyboard.TargetProperty="Background.Color" To="Goldenrod" Duration="0:0:0.2" />
                <ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="Goldenrod" Duration="0:0:0.2" />
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ellipse">
                    <SplineDoubleKeyFrame KeyTime="0" Value="0"/>
                    <SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="15" KeySpline="0, 1, 0.6, 1"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </BeginStoryboard>
    </MultiDataTrigger.EnterActions>
    <MultiDataTrigger.ExitActions>
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation Storyboard.TargetProperty="Background.Color" To="#FAFAFB" Duration="0:0:0.2" />
                <ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#EAEAEB" Duration="0:0:0.2" />
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ellipse">
                    <SplineDoubleKeyFrame KeyTime="0" Value="15"/>
                    <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0" KeySpline="0, 0.5, 0.5, 1"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </BeginStoryboard>
    </MultiDataTrigger.ExitActions>
</MultiDataTrigger>

I'm not sure what I'm doing wrong, using a regular trigger makes the animation work. Here's a look at the trigger.

<Trigger Property="IsChecked" Value="true" >
    <Trigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation Storyboard.TargetProperty="Background.Color" To="#FF377EC1" Duration="0:0:0.2" />
                <ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#FF377EC1" Duration="0:0:0.2" />
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ellipse">
                    <SplineDoubleKeyFrame KeyTime="0" Value="0"/>
                    <SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="15" KeySpline="0, 1, 0.6, 1"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </BeginStoryboard>
    </Trigger.EnterActions>
    <Trigger.ExitActions>
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation Storyboard.TargetProperty="Background.Color" To="#FAFAFB" Duration="0:0:0.2" />
                <ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="#EAEAEB" Duration="0:0:0.2" />
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TranslateTransform.X)" Storyboard.TargetName="ellipse">
                    <SplineDoubleKeyFrame KeyTime="0" Value="15"/>
                    <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0" KeySpline="0, 0.5, 0.5, 1"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </BeginStoryboard>
    </Trigger.ExitActions>
</Trigger>
2
How and where is Myself defined? I would think the binding to Status should be {Binding Status, RelativeSource={RelativeSource Self} (or RelativeSource TemplatedParent, if this is in a ControlTemplate), but I may be missing something.15ee8f99-57ff-4f92-890c-b56153
ElementName is the problem in your first case because of namescope issues.AnjumSKhan
You both are correct, I had forgotten that we had done something similar to this in a different control and aliased Myself=Self. By doing RelativeSource={RelativeSource Self} it works. Thanks for all the help!CGideon

2 Answers

1
votes

I can't find a definition for Myself in your XAML.

If this is in Style.Triggers (I'm pretty sure it is), I would think the binding to Status should be {Binding Status, RelativeSource={RelativeSource Self}, just like your IsChecked binding.

If I'm wrong and it's in ControlTemplate.Triggers, I would try {Binding Status, RelativeSource={RelativeSource TemplatedParent} -- and the same for IsChecked.

0
votes

The problem was with <Condition Binding="{Binding Status,ElementName=Myself}" Value="Modified"/> all I had to do was switch it to <Condition Binding="{Binding Status, RelativeSource={RelativeSource=Self}}" Value="Modified"/>

This change fixes the styling triggers.