Storyboard.GetTarget in Silverlight for Windows Mo

2019-02-15 18:19发布

问题:

I have a problem with WP7 app. I'm trying to write WP7 app form WPF sample code.

    private void storyboard_Completed(object sender, EventArgs e)
    {
        ClockGroup clockGroup = (ClockGroup)sender;

        // Get the first animation in the storyboard, and use it to find the
        // bomb that's being animated.
        DoubleAnimation completedAnimation = (DoubleAnimation)clockGroup.Children[0].Timeline;
        Bomb completedBomb = (Bomb)Storyboard.GetTarget(completedAnimation);

it seems that there is no ClockGroup class and Storyboard does not have GetTarget method (which is a bit strange cuz there is SetTarget method). Is there a hack to get he same functionality?

回答1:

I know little of WPF but in Silverlight or WP7 the children of a Storyboard are of type TimeLine. Also a StoryBoard itself would have a Completed event to which you would be binding. So at least the first chunk of the code would look like:-

private void storyboard_Completed(object sender, EventArgs e)
{
    Storyboard sb = (Storyboard)sender;

    DoubleAnimation completedAnimation = (DoubleAnimation)sb.Children[0];

Now for the tricky bit.

Its actually quite unusual for Storyboard.SetTarget to be used in Silverlight code. I guess that game code is more likely to generate elements and animations in code and therefore more likely to use SetTarget. If this is what you want to do then you will need to build your own attached property that has both Get and Set, have the changed callback on this property call the Storyboard.SetTarget.

Here is the code:-

public static class StoryboardServices
{
    public static DependencyObject GetTarget(Timeline timeline)
    {
        if (timeline == null)
            throw new ArgumentNullException("timeline");

        return timeline.GetValue(TargetProperty) as DependencyObject;
    }

    public static void SetTarget(Timeline timeline, DependencyObject value)
    {
        if (timeline == null)
            throw new ArgumentNullException("timeline");

        timeline.SetValue(TargetProperty, value);
    }

    public static readonly DependencyProperty TargetProperty =
            DependencyProperty.RegisterAttached(
                    "Target",
                    typeof(DependencyObject),
                    typeof(Timeline),
                    new PropertyMetadata(null, OnTargetPropertyChanged));

    private static void OnTargetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Storyboard.SetTarget(d as Timeline, e.NewValue as DependencyObject);
    }
}

Now the SetTarget code would become:-

 StoryboardServices.SetTarget(completedAnimation, bomb);

Then your completed event can retrieve the target with:-

 Bomb completedBomb = (Bomb)StoryboardServices.GetTarget(completedAnimation);