I've searched all over and can't seem to find an answer on this one. My app lives in the world of loose XAML so has to rely on XamlReaders and tree walking to find elements. I have a component that handles the rendering of these XAML pages. That renderer needs to know the state of storyboards that could be running on the loaded XAML. So what I'd like to do in my renderer is something like this: -
var resources = _currentScreenFrameworkElement.Resources;
foreach (var item in resources.Values)
{
if (item is Storyboard)
{
try
{
var storyboard = item as Storyboard;
**if (storyboard.GetCurrentState() == ClockState.Active)**
All well and good. However the problem is when I try an dcheck the CurrentState it throws an exception: -
"Cannot perform action because the specified Storyboard was not applied to this object for interactive control."
Looking around I see it's because I need to make the storyboard controllable. So my question is how do I do this in XAML? I don't start the storyboard in code so can't pass true into the overloaded BeginStoryboard.
I just ran into this same problem so i figured i'd share my findings.
You get that error when your storyboard is not marked as Controllable. Storyboards are marked as Controllable when the Begin method is called.
If you're doing it from code behind then you just use an overload that has this IsControllable
boolean argument (list of Begin overloads).
If you've used the BeginAnimation element in Xaml then you'll need to do 2 things.
Name
to the BeginAnimation element. The documentation for this property states: "If the Name of BeginStoryboard is unspecified, the Storyboard cannot be interactively affected after it is begun"Here's an example showing you step 1 (name the beginstoryboard)
<Button Name="btn1" Content="bla">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard
Name="bnt1_beginStoryboard"
Storyboard={StaticResource someSharedStoryboard}"/>
</EventTrigger>
</Button.Triggers>
</Button>
and here's an example for step 2. Since you've named your beginStoryboard you can use that as a local variable in your class.. or you can just reference the actual storyboard directly. The main point is that you must pass in the owner of the beginStoryboard (which is the button in this case)
//The main point here is that we're passing in btn1
bnt1_beginStoryboard.Storyboard.Stop(btn1);
bnt1_beginStoryboard.Storyboard.SkipToFill(btn1);
bnt1_beginStoryboard.Storyboard.Resume(btn1);
Here's a list of all the "action" methods on a storyboard that require you to pass in the owning framework element: Control a Storyboard After It Starts
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With