Is it possible to change the storyboard.targetname's value by Javascript?
I've tried to use Javascript to change the value of storyboard.targetname and storyboard.targetproperty, but it is not work.
If it is supported in the future, that will be very wonderful. we can create a canvas.triggers at first, and use js to change the storyboard's value in the canvas and begin it.
At now, in my UI project which is used in wpf/e , i only can create all the storyboard where i will be used at first, and start them one by one. The XAML code is very long ...
This is a limitation of the current build. However, you don't have to trigger them one-by-one. For instance, here is a simple example of animating multiple gradient stops of a gradient brush and they are all triggered by the TextBlock loading:
<TextBlock Text="A" FontSize="108">
<TextBlock.Foreground>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop x:Name="Gs5" Color="Black" Offset="-3.6" />
<GradientStop x:Name="Gs4" Color="#ff007300" Offset="-0.6" />
<GradientStop x:Name="Gs3" Color="#ff94FFAB" Offset="-0.5" />
<GradientStop x:Name="Gs2" Color="#ff94FFAB" Offset="0.0" />
<GradientStop x:Name="Gs1" Color="Black" Offset="0.1" />
</LinearGradientBrush>
</TextBlock.Foreground>
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Gs1"
Storyboard.TargetProperty="Offset"
From="0.1" To="1" Duration="0:0:0.9" />
<DoubleAnimation
Storyboard.TargetName="Gs2"
Storyboard.TargetProperty="Offset"
From="0" To="1" Duration="0:0:1" />
<DoubleAnimation
Storyboard.TargetName="Gs3"
Storyboard.TargetProperty="Offset"
From="-0.5" To="1" Duration="0:0:1.5" />
<DoubleAnimation
Storyboard.TargetName="Gs4"
Storyboard.TargetProperty="Offset"
From="-0.6" To="1" Duration="0:0:1.6" />
<DoubleAnimation
Storyboard.TargetName="Gs5"
Storyboard.TargetProperty="Offset"
From="-3.6" To="1" Duration="0:0:4.6" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
This is unfortunately not supported. The way to accomplish this is by creating a new dummy Canvas with a new Storyboard each time. Each new Storyboard can have the new TargetName, and it will begin as soon as the dummy Canvas is added to the main tree. If you want to clean up old Storyboards, just remove the dummy Canvas associated with it from the main tree.
Hope this helps,
Ed Maia
WPF/E Program Manager
I used the method of adding a new Canvas with a new StoryBoard and DoubleAnimation affecting (Canvas.Top). When I run storyBoard.begin(), the Target immediately changes positions with no animation in between. I found that if I added a javascript alert between adding the new Canvas and running storyBoard.begin(), the animation will render. How can I get around this?
XAML:
<
Canvas Name="cnvsStoryBoard"><
Canvas.Triggers><
EventTrigger><
EventTrigger.Actions><
BeginStoryboard Name="beginStoryBoard"><
Storyboard Name="storyBoard" BeginTime="5" Duration="0:0:1" AutoReverse="false" ><
DoubleAnimation Name="animTop" Storyboard.TargetName="cnvsBoard" Storyboard.TargetProperty="(Canvas.Top)" To="0"/></
Storyboard></
BeginStoryboard></
EventTrigger.Actions></
EventTrigger></
Canvas.Triggers></
Canvas><
CanvasName="cnvsBoard"Loaded="javascript:boardLoaded"Canvas.Left="200"Canvas.Top="200"><
Rectangle Height="162" Width="162"Stroke="White" StrokeThickness="1" Fill="Gray"/></
Canvas>
Javascript:
// The DoubleAnimation's Storyboard.TargetName cannot be set at runtime
// DoubleAnimations cannot be removed and added at runtime// DoubleAnimation plays when removed (below) if it isn't "stopped" firstvar storyBoard = sender.findName("storyBoard");storyBoard.stop();
// Remove cnvsStoryBoardvar cnvsStoryBoard = sender.findName("cnvsStoryBoard");cnvsRoot.children.remove(cnvsStoryBoard);
// Build new Canvas with StoryBoard and new DoubleAnimation with new property valuesvar cnvsStoryBoardXaml = "<Canvas Name='cnvsStoryBoard'>" +"<Canvas.Triggers>" +"<EventTrigger>" +"<EventTrigger.Actions>" +"<BeginStoryboard>" +"<Storyboard Name='storyBoard' BeginTime='5' Duration='0:0:10' AutoReverse='false' >"// Create dynamic DoubleAnimationvar animXaml = "<DoubleAnimation Name='$animName' Storyboard.TargetName='$targetName' Storyboard.TargetProperty='$targetProperty' To='$targetValue'/>"var newAnimXaml = animXaml;newAnimXaml = newAnimXaml.replace(
"$animName", "animTop");newAnimXaml = newAnimXaml.replace(
"$targetName", "cnvsBoard");newAnimXaml = newAnimXaml.replace(
"$targetProperty", "(Canvas.Top)");newAnimXaml = newAnimXaml.replace(
"$targetValue", "10");cnvsStoryBoardXaml = cnvsStoryBoardXaml + newAnimXaml;
cnvsStoryBoardXaml = cnvsStoryBoardXaml +
"</Storyboard>" +"</BeginStoryboard>" +"</EventTrigger.Actions>" +"</EventTrigger>" +"</Canvas.Triggers>" +"</Canvas>";// Create new Canvas objectvar cnvsStoryBoard = control.createFromXaml(cnvsStoryBoardXaml);// Add new Canvas to the root CanvascnvsRoot.children.add(cnvsStoryBoard);
// Get a reference to the new StoryBoardstoryBoard = cnvsStoryBoard.findName(
"storyBoard");// Adding an alert is the only way I have found to cause the animation to Render// If the alert is not added, the animation will happen in 0 seconds (storyBoard.Duration.seconds = 0)// In this example, the animation's Target will immediately change positions with no animation in betweenalert(
"Render animation...");storyBoard.begin();
I found a way around the issue. I still don't know what causes the behavior posted previously.
Using a BeginTime='0:0:0" and removing the storyBoard.begin(); will cause the animation to render properly and begin immediately after it is added to the Canvas:
"<Storyboard Name='storyBoard' BeginTime='0:0:0' Duration='0:0:10' AutoReverse='false' >"
....
// storyBoard.begin();