WPF Animation with datatriggers

2019-05-21 03:39发布

问题:

I have a rectangle which I am animating the backround colour of.

It should change to green each time a particular number goes up. And red when it goes dowm. If the number doesn't change for a while it slowly fades back to its default colour

So the animation changes th background from grey to red very quickly and then takes several seconds to fade back to grey.

I have added as DataTrigger which is bound to 1 or -1 depending on how the number has changed

The problem is that if the number keeps going up the animation does not get restarted.

e.g. if the sequence of numbers went 1, 2, 3, 4, 5. Then I would like the animation to restart at each number change

the code I am using is below

<Rectangle.Style>
    <Style>
        <Style.Triggers>
            <DataTrigger Binding="{Binding BidChangeDirectionIndicator}"
                         Value="-1">
                <DataTrigger.EnterActions>
                    <BeginStoryboard x:Name="bidDownStory">
                        <Storyboard>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                <EasingColorKeyFrame KeyTime="0"
                                                     Value="#FF79797A" />
                                <EasingColorKeyFrame KeyTime="0:0:0.2"
                                                     Value="#FFF13B29" />
                                <EasingColorKeyFrame KeyTime="0:0:10.0"
                                                     Value="#FF79797A" />
                            </ColorAnimationUsingKeyFrames>
                            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
                                <EasingColorKeyFrame KeyTime="0"
                                                     Value="#FF2B2B2B" />
                                <EasingColorKeyFrame KeyTime="0:0:0.2"
                                                     Value="#FF3F0606" />
                                <EasingColorKeyFrame KeyTime="0:0:10.0"
                                                     Value="#FF2B2B2B" />
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </DataTrigger.EnterActions>
                <DataTrigger.ExitActions>
                    <StopStoryboard BeginStoryboardName="bidDownStory" />
                </DataTrigger.ExitActions>
            </DataTrigger>
        </Style.Triggers>
    </Style>

and the ViewModel I am binding to looks like this

private int _bidChangeDirectionIndicator;
public int BidChangeDirectionIndicator
{
    get { return _bidChangeDirectionIndicator; }
    set
    {
        _bidChangeDirectionIndicator = value;
        RaisePropertyChanged("BidChangeDirectionIndicator");
    }
}

....

public void Update(RateInfo rateInfo)
{
    if (rateInfo.Bid != Bid)
    {
        BidChangeDirectionIndicator = Math.Sign(rateInfo.Bid - Bid);
    }            
}

The method gets called each time the number changes (this is done by a class which is listening to an external feed)

回答1:

[Caveat: I have not had time to recreate and test this. I just thought it may help.]

The reason that the trigger does not fire is that the value does not change. When you, for instance, keep going up, the value of BidChangeDirectionIndicator remains 1.

Perhaps the simplest thing to do is to set it to another value (0), and then to the value you want.

public void Update(RateInfo rateInfo)
{
    if (rateInfo.Bid != Bid)
    {
        BidChangeDirectionIndicator = Math.Sign(rateInfo.Bid - Bid);
    }            
    else
    {
        BidChangeDirectionIndicator = 0;
        BidChangeDirectionIndicator = rateInfo.Bid;
    }
}