Classic storyboard problem

3,168 views
Skip to first unread message

Marlon Grech

unread,
Sep 14, 2009, 3:36:09 PM9/14/09
to wpf-di...@googlegroups.com
Storyboards and Dependency properties play dirty tricks on us WPF developers. Sometimes you do an animations and once the animation is finished you want to be able to set the animated property from somewhere else... Yet the problem is that a Storyboard holds the value that it animated and you can set the property any more..

I found this article on MSDN on how to fix this... yet this involves hooking to the completed event etc... which 1. It is not nice! 2. you cannot do it if you are in a style. The XAML below shows a classic example.

<Style BasedOn="{StaticResource baseBorder}" TargetType="Border"
                       >
                    <Setter Property="Height" Value="100"/>
                    <Setter Property="Width" Value="100"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding FirstItemExpanded}" Value="True"
                                     local:StoryboardBehaviour.SetValuesWhenCompleted="True">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard >
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="Height" To="300" />
                                        <DoubleAnimation Storyboard.TargetProperty="Width" To="300"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>

What I had in mind was to do an attached behavior that does this for you... Yet it is not that easy. If the Storyboard is in a style than you do not have the target element the storyboard is dealing with and thus you cannot set the value of the property :S 

Anyone ever did anything about this issue?

Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App

Marlon Grech

unread,
Sep 14, 2009, 3:42:00 PM9/14/09
to wpf-di...@googlegroups.com
This is the property changed handler that I was trying to do for the attached behaviour

 private static void OnSetValuesWhenCompletedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue)
            {
                Storyboard animation = (Storyboard)d;
                animation.Completed += delegate
                {
                    var target = GetStoryboardTarget(animation); // this is the problem... how do I get the Target??
                    foreach (var item in animation.Children)
                    {
                        PropertyPath path = Storyboard.GetTargetProperty(item);
                        var prop = DependencyPropertyDescriptor.FromName(path.Path,
                            target.GetType(), target.GetType()).DependencyProperty;
                        target.SetValue(prop, target);
                    }
                };
            }
        }

and this is how you would do the behaviour in XAML
<DataTrigger.EnterActions>
      <BeginStoryboard >
           <Storyboard local:StoryboardBehaviour.SetValuesWhenCompleted="True">

               <DoubleAnimation Storyboard.TargetProperty="Height" To="300" />
               <DoubleAnimation Storyboard.TargetProperty="Width" To="300"/>
            </Storyboard>
      </BeginStoryboard>
</DataTrigger.EnterActions>

The problem is how do I get the Target of the storyboard ??? I tried various ways... I tried to do another attached property so that the user can set it via binding relative source. It would have looked like this

<Storyboard local:StoryboardBehaviour.SetValuesWhenCompleted="True"
    local:StoryboardBehaviour.StoryboardTarget="{Binding RelativeSource={RelativeSource AncestoryType={x:Type Border}}}">

But this raises an exception because you cannot use binding in there :( There must be a way to get the Storyboard target!!! WPF is updating the values of properties so the Storyboard is getting a reference of the element from somewhere isn't it!!!!

Any help would be awsome ... Thanks

Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Marlon Grech

unread,
Sep 14, 2009, 3:44:25 PM9/14/09
to wpf-di...@googlegroups.com
sorry to spam you.... but I forgot to give you the exception you get when trying to do that binding

System.Windows.Style' value cannot be assigned to property 'Style' of object 'System.Windows.Controls.Border'. Cannot freeze this Storyboard timeline tree for use across threads.

Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



On Mon, Sep 14, 2009 at 8:36 PM, Marlon Grech <marlo...@gmail.com> wrote:

Sacha Barber

unread,
Sep 14, 2009, 3:46:00 PM9/14/09
to wpf-di...@googlegroups.com
No never had that issue


Date: Mon, 14 Sep 2009 20:44:25 +0100
Subject: [WPF Disciples] Re: Classic storyboard problem
From: marlo...@gmail.com
To: wpf-di...@googlegroups.com

Add other email accounts to Hotmail in 3 easy steps. Find out how.

Marlon Grech

unread,
Sep 14, 2009, 3:49:11 PM9/14/09
to wpf-di...@googlegroups.com
Found how WPF gives the target to the Storyboard and as usual the framework is not open for anyone else

internal sealed override void Invoke(FrameworkElement fe) { this.Begin(fe, null, Storyboard.Layers.ElementEventTrigger); }

:(

 any workarounds??


Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Laurent Bugnion, GalaSoft

unread,
Sep 15, 2009, 3:56:47 AM9/15/09
to wpf-di...@googlegroups.com

Hey Marlon,

 

You can specify how the storyboard behaves at the end of the animation, using the FillBehavior property and setting it to Stop. It means that the Storyboard will no longer hold the value after it is completed.

 

Greetings,

Laurent

Marlon Grech

unread,
Sep 15, 2009, 4:42:34 AM9/15/09
to wpf-di...@googlegroups.com
if only it was that simple dude :)

The problem with doing that is that when you set to Stop the Storyboard releases the values and the values go back to being the same as before the animation... So if you animate a width property from 10 to 80, with stop when the animation finishes width goes back to 10


Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Mike Brown

unread,
Sep 15, 2009, 11:04:17 AM9/15/09
to wpf-di...@googlegroups.com
What if you define a new boolean attached property and create a trigger from that? You could then use the Exit action to remove the animation.

Marlon Grech

unread,
Sep 15, 2009, 11:08:55 AM9/15/09
to wpf-di...@googlegroups.com
didn't get that


Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Mike Brown

unread,
Sep 15, 2009, 11:25:10 AM9/15/09
to wpf-di...@googlegroups.com
You can run an animation from a property trigger. What if you created an attachedbehavior that is backed by a boolean viewmodel property. The property is true when the animation needs to beging (that will be your enter action for the trigger) the exit action for the trigger reverses the animation with a Stop fillbehavior. You set the backing property to false and the exit action will effectively remove the animation and remove the lock on the property.

Marlon Grech

unread,
Sep 15, 2009, 11:29:53 AM9/15/09
to wpf-di...@googlegroups.com
there are simple workarounds such as instead a DataTrigger in a style you do something else.... what I needed was more as such to find out if you guys ever did anything like this for DataTriggers and storyboards
Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Eric Burke

unread,
Sep 15, 2009, 12:30:09 PM9/15/09
to wpf-di...@googlegroups.com
One way to do it is to use the public-but-undocumented Storyboard.Target attached property.  This allows you to set an object as the target instead of setting a TargetName and having WPF figure out what the target is.
 
Here's one way to use it, which requires a level of indirection because an ElementName binding doesn't work.  I also don't know how this will work when it comes to template reuse.  But maybe this helps you find a different solution.
 

<DataTemplate

    x:Key="dt">

    <DataTemplate.Resources>

        <TextBlock

            x:Key="txt"

            FontSize="12"

            Text="{Binding Name}" />

     </DataTemplate.Resources>

    <ContentPresenter

        Content="{StaticResource txt}" />

     <DataTemplate.Triggers>

        <DataTrigger

            Binding="{Binding Path=IsAnimating}"

            Value="True">

            <DataTrigger.EnterActions>

                <BeginStoryboard>

                    <Storyboard>

                        <DoubleAnimation

                            Storyboard.Target="{StaticResource txt}"

                            Storyboard.TargetProperty
="FontSize"

                            To
="18"

                            Duration
="0:0:2"

                            CurrentStateInvalidated
="DoubleAnimation_CurrentStateInvalidated"

                            FillBehavior
="Stop" />

                     </Storyboard>

                </BeginStoryboard>

            </DataTrigger.EnterActions>

        </DataTrigger>

    </DataTemplate.Triggers>

</DataTemplate>
 
--
eric burke
ebu...@yahoo.com



From: Marlon Grech <marlo...@gmail.com>
To: wpf-di...@googlegroups.com
Sent: Tuesday, September 15, 2009 11:29:53 AM

Subject: [WPF Disciples] Re: Classic storyboard problem

Marlon Grech

unread,
Sep 15, 2009, 12:45:33 PM9/15/09
to wpf-di...@googlegroups.com
Tried that but you cannot set the Target if you are in a style :(

Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Mike Brown

unread,
Sep 15, 2009, 1:16:34 PM9/15/09
to wpf-di...@googlegroups.com
Lately I've been taking what I'd normally put in a DataTemplate or Style (like an ItemsTemplate) and making a UserControl with a backing VM and making that UserControl the content of the template. Would that address your issue?

Mike Brown

unread,
Sep 15, 2009, 1:17:44 PM9/15/09
to wpf-di...@googlegroups.com
Note in this scenario your animation would be part of the UserControl

Marlon Grech

unread,
Sep 15, 2009, 1:25:32 PM9/15/09
to wpf-di...@googlegroups.com
what I wanted to do is a generic attached behaviour... I fixed my problem by using StopStoryboard ... yet for me this suck a bit!

Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Peter O'Hanlon

unread,
Sep 15, 2009, 2:44:19 PM9/15/09
to wpf-di...@googlegroups.com
Why do I feel like coughing into my fist and shouting "nasty hack"?
--
Peter O'Hanlon

Laurent Bugnion, GalaSoft

unread,
Sep 15, 2009, 4:14:38 PM9/15/09
to wpf-di...@googlegroups.com

Did you try with a Blend behavior? The samples on Codeplex have an action that can trigger a VM command when an event is raised. I wonder if you could use that to talk to your VM when Storyboard.Completed is fired.

 

Cheers,

Marlon Grech

unread,
Sep 15, 2009, 4:23:33 PM9/15/09
to wpf-di...@googlegroups.com
I didn't try that yet ... but I have my doubts it would work since I looked in reflector and when you are in a Style the target get set silently by the framework and there is not way of getting that reference :S


Regards
Marlon
WPF Blog - http://marlongrech.wordpress.com/
Microsoft MVP for Client App



Karl Shifflett

unread,
Sep 16, 2009, 12:34:51 AM9/16/09
to wpf-di...@googlegroups.com

k-dawg after programming until 2:00am for 4 days working on day 5.

 

I was going to do some pyrotechnics at FireStarter but determined I don’t need the fire department on my 6; so I settled for the “flaming matchstick look.”

 

 

               

image001.png

Corrado Cavalli

unread,
Sep 16, 2009, 1:28:26 AM9/16/09
to wpf-di...@googlegroups.com

ROTFL!

 

From: wpf-di...@googlegroups.com [mailto:wpf-di...@googlegroups.com] On Behalf Of Karl Shifflett


Sent: mercoledì 16 settembre 2009 06:35
To: wpf-di...@googlegroups.com

image001.png

Karl Shifflett

unread,
Sep 16, 2009, 1:33:46 AM9/16/09
to wpf-di...@googlegroups.com

I’m thinking for the MVP Summit, WPF Disciples should all go “bright green

image001.png

Corrado Cavalli

unread,
Sep 16, 2009, 2:17:25 AM9/16/09
to wpf-di...@googlegroups.com

J I’ll start looking for a “bright green” wig…

 

From: wpf-di...@googlegroups.com [mailto:wpf-di...@googlegroups.com] On Behalf Of Karl Shifflett


Sent: mercoledì 16 settembre 2009 07:34
To: wpf-di...@googlegroups.com

Subject: [WPF Disciples] Re: Starting Fires

 

I’m thinking for the MVP Summit, WPF Disciples should all go “bright green

 

image001.png

Karl Shifflett

unread,
Sep 16, 2009, 2:26:59 AM9/16/09
to wpf-di...@googlegroups.com

Now we are talking!

image001.png

Sacha Barber

unread,
Sep 16, 2009, 3:51:11 AM9/16/09
to wpf-di...@googlegroups.com
Now all you need is one of those Hawaiin shirts with say a volcano on it and some hot lava spilling forth. Awesome look k-dawg
 

From: mole...@comcast.net
To: wpf-di...@googlegroups.com
Subject: [WPF Disciples] Starting Fires
Date: Tue, 15 Sep 2009 21:34:51 -0700


k-dawg after programming until 2:00am for 4 days working on day 5.

 

I was going to do some pyrotechnics at FireStarter but determined I don’t need the fire department on my 6; so I settled for the “flaming matchstick look.”

 

 

               



View your other email accounts from your Hotmail inbox. Add them now.
image001.png

Peter O'Hanlon

unread,
Sep 16, 2009, 4:01:28 AM9/16/09
to wpf-di...@googlegroups.com
It looks like k-dawg is at the start of a set of Andy Warhol prints. The next one will be green Karl, then yellow, blue and finally purple.
--
Peter O'Hanlon
image001.png

Karl Shifflett

unread,
Sep 16, 2009, 4:43:32 AM9/16/09
to wpf-di...@googlegroups.com

I tried to find a Flames shirt for the last month.  Vendors were back ordered!  I was bummed.  I didn’t think of the lava flow, next time for sure, thanks for the great idea!

image001.png

Karl Shifflett

unread,
Sep 16, 2009, 4:49:17 AM9/16/09
to wpf-di...@googlegroups.com

Pete, we gott’a keep’m guess’n!

 

BTW:  I’m polishing up the next version of XAML Power Toys.

 

I’ve spend 4 days working on this motha.

 

Many new features including support for the Silverlight DataForm.

 

Getting the secondary appdomain assembly reflection issues sorted out took much longer than I expected, hence the 2:00am keyboard sessions.  But it’s now working flawlessly.  (stress gone!)

 

I’m introducing it at FireStarter Thursday and will put on my blog Sunday.  Josh is coming over Saturday so I’ll let him have at it one more time before I release v5.  Got to do the videos too for the new features.

 

Cheers,

 

k-dawg

Peter O'Hanlon

unread,
Sep 16, 2009, 4:53:04 AM9/16/09
to wpf-di...@googlegroups.com
Cool - I'm looking forward to seeing it. Once I've finished the MVVM framework I'm working on (and demo apps for it), I'll be getting back to MoXAML - it's due a major refactoring. I'm looking to moving it to a plugin architecture so that new commands can be dropped in without having to recompile the base services (and to look at VS2010 integration).
--
Peter O'Hanlon

Karl Shifflett

unread,
Sep 16, 2009, 5:04:31 AM9/16/09
to wpf-di...@googlegroups.com

Nice idea.  Assume you’ll use MEF?

 

What I’m drooling over is T4 Preprocessed Text Templates in Visual Studio 2010 Beta1 and later.  These make T4 MUCH better than 2008.  One step instead of two.  Read this two short blog posts that clearly explain the concept and implementation.

 

http://www.clariusconsulting.net/blogs/pga/archive/2009/07/15/160836.aspx

 

http://www.clariusconsulting.net/blogs/pga/archive/2009/7/15.aspx

 

These puppies make code gen incredibly simple.

 

I wrote one in a few minutes to generate types.  This is what I’ll be working on in Oct.

Daniel Vaughan

unread,
Sep 16, 2009, 5:07:42 AM9/16/09
to WPF Disciples
Love it!

On Sep 16, 6:34 am, "Karl Shifflett" <molena...@comcast.net> wrote:
> k-dawg after programming until 2:00am for 4 days working on day 5.
>
> I was going to do some pyrotechnics at FireStarter but determined I don't
> need the fire department on my 6; so I settled for the "flaming matchstick
> look."
>
>  image001.png
> 510KViewDownload

Peter O'Hanlon

unread,
Sep 16, 2009, 5:09:37 AM9/16/09
to wpf-di...@googlegroups.com
Cool, and yes, I'll be using MEF. This is the whole reason I'm decoupling the feature implementations from the underlying IDE integration - it means the same codebase should be able to serve both environments.
 
I like the look of the templates, I'll probably drop a couple of MoXAML tools in favour of T4 implementations.

--
Peter O'Hanlon

Karl Shifflett

unread,
Sep 16, 2009, 5:16:05 AM9/16/09
to wpf-di...@googlegroups.com

J

-----Original Message-----
From: wpf-di...@googlegroups.com [mailto:wpf-di...@googlegroups.com] On Behalf Of Daniel Vaughan
Sent: Wednesday, September 16, 2009 2:08 AM
To: WPF Disciples
Subject: [WPF Disciples] Re: Starting Fires

 

 

Love it!

Laurent Bugnion, GalaSoft

unread,
Sep 16, 2009, 5:18:00 AM9/16/09
to wpf-di...@googlegroups.com

Wig? No Corrado you’re supposed to dye your hairs……… oh wait….. ;)

image001.png

Josh Smith

unread,
Sep 16, 2009, 9:05:26 AM9/16/09
to wpf-di...@googlegroups.com
Nice look, Big Red!
image001.png
Reply all
Reply to author
Forward
0 new messages