I am using Syncfusion WPF components 28.1.41 in a my WPF .Net application. I am using the SfStepProgressBar and most of the time it behaves perfectly. However sometimes I seem to get an unhandled exception "No target specified for DoubleAnimation", and the stack trace always seems to show this is due to a call from the SfStepProgressBar. It is inconsistant as the same "inputs" mostly work, but sometimes don't. It's not that my code has failed to specify any "target", because my definitions would be the same each time.
My latest exception shows that it was this line in Storyboard.cs which raised the exception
And here is the stack trace
Here are the definitions of my storyboards used for the animation
<!-- Define the storyboard for Image zoom animation -->
<Storyboard x:Key="ZoomImageStoryboard">
<!-- Animate the ScaleX and ScaleY properties to zoom the image -->
<DoubleAnimation
Storyboard.TargetName="ImageTransform"
Storyboard.TargetProperty="ScaleX"
From="1.0" To="1.1" Duration="0:0:0.2" AutoReverse="True" RepeatBehavior="3x"/>
<DoubleAnimation
Storyboard.TargetName="ImageTransform"
Storyboard.TargetProperty="ScaleY"
From="1.0" To="1.1" Duration="0:0:0.2" AutoReverse="True" RepeatBehavior="3x"/>
</Storyboard>
<!-- Define the storyboard for Text zoom animation -->
<Storyboard x:Key="ZoomTextStoryboard">
<!-- Animate ScaleX (horizontal scaling) -->
<DoubleAnimation Storyboard.TargetName="TextTransform"
Storyboard.TargetProperty="ScaleX"
From="1.0" To="2.0" Duration="0:0:0.3" AutoReverse="True"/>
<!-- Animate ScaleY (vertical scaling) -->
<DoubleAnimation Storyboard.TargetName="TextTransform"
Storyboard.TargetProperty="ScaleY"
From="1.0" To="2.0" Duration="0:0:0.3" AutoReverse="True"/>
</Storyboard>
And here is a single DataTemplate used for one of the stamp states, which includes the triggering of the animation
<!--- Player has this stamp, and there is an unclaimed reward -->
<DataTemplate x:Key="RewardUnclaimedStamp">
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- Show "Unclaimed" but give it some animation to attract the eye -->
<TextBlock Grid.Row="0" Text="Unclaimed!" FontSize="27" Foreground="LimeGreen" FontWeight="Bold" HorizontalAlignment="Center">
<TextBlock.RenderTransform>
<ScaleTransform x:Name="TextTransform"/>
</TextBlock.RenderTransform>
<TextBlock.RenderTransformOrigin>
<!-- Center of the TextBlock -->
<Point X="0.5" Y="0.5"/>
</TextBlock.RenderTransformOrigin>
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
<BeginStoryboard Storyboard="{StaticResource ZoomTextStoryboard}"/>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
<TextBlock Grid.Row="1" Text="{Binding RewardTitle}"
Width="140" TextWrapping="Wrap"
FontSize="27" TextAlignment="Center" />
</Grid>
</DataTemplate>
If I was principally just doing things wrong, I would expect it not to work, or give me these exceptions all the time. But it works 99% of the time.
Is there anything you can spot, which you would advise me I am not applying correctly?
Thanks, Paul
Hi Paul,
We could not reproduce the reported issue using the information provided. For your reference, we’ve attached a sample that we used to try to replicate the issue on our end. Can you please modify the attached sample as per your sample and share it back with us with detailed replication steps. This will assist us in conducting a more thorough investigation.
Yathavakrishnan M
Hi,
Thanks for replying and providing the template to modify. I think it may take some time as my application's use of the SfStepProgressBar is a little more complex than I originally described. But having given this further thought, I think it might be very relevant to my problem....
We use the SfStepProgressBar as a representation of a "stampcard", each having a unique layout (no. of markers, marker images, marker text...). Our users can switch between different stampcards, thereby causing me to need to redefine the SfStepProgressBar's properties. I have noted that this issue appears to occur most often when the user moves between stampcards, perhaps before the animations on the marker's controls from the previous stampcard has finished animating. FYI, I have animation on both the marker image and text, if a "stamp" is of a certain state only. There could be none, one, or multiple stamps with this same state and animating.
As my code knows it is redefining the layout, I am thinking it should do something to either stop any animations in progress, or wait until they complete.
Now I have further explained my application a little, do my reasonings on the possible issue sound likely? Can you suggest any way that I can cancel/freeze updates/animations on the SfStepProgressBar whilst I am updating it's properties?
Thanks, Paul
Hi Paul,
We can achieve your
requirement by using the AnimationDurationProperty . The default value of the
AnimationDuration property is 500ms. To meet your requirement, set the
AnimationDuration property to 0, it will complete the animation before another one is executed.
Please refer to the code snippet below and the user guide link for more
details.
|
//set the
Animation duration |
UG Link : Selected Item in WPF Step
ProgressBar control | Syncfusion<sup>®</sup>;
Hi. That's a great suggestion, but wouldn't that only affect the animation of the progress marker line? In reality I have added animation to some of the markers images and text
For example, my marker image is supplied via a datatemplater selector
<DataTemplate x:Key="RewardUnclaimedMarker">
<Grid>
<!-- Show "Redeem Now" icon but give it some animation to attract the eye -->
<Image Source="/FrontEnd;component/Images/RedeemNowIcon.png" Width="100" Height="100">
<Image.RenderTransform>
<ScaleTransform x:Name="ImageTransform"/>
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<BeginStoryboard Storyboard="{StaticResource ZoomImageStoryboard}"/>
</EventTrigger>
</Image.Triggers>
</Image>
</Grid>
</DataTemplate>
and my marker text has it's own DataTemplate provided by a different selector
<DataTemplate x:Key="RewardUnclaimedStamp">
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- Show "Unclaimed" but give it some animation to attract the eye -->
<TextBlock Grid.Row="0" Text="Unclaimed!" FontSize="27" Foreground="LimeGreen" FontWeight="Bold" HorizontalAlignment="Center">
<TextBlock.RenderTransform>
<ScaleTransform x:Name="TextTransform"/>
</TextBlock.RenderTransform>
<TextBlock.RenderTransformOrigin>
<!-- Center of the TextBlock -->
<Point X="0.5" Y="0.5"/>
</TextBlock.RenderTransformOrigin>
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
<BeginStoryboard Storyboard="{StaticResource ZoomTextStoryboard}"/>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
<TextBlock Grid.Row="1" Text="{Binding RewardTitle}"
Width="140" TextWrapping="Wrap"
FontSize="27" TextAlignment="Center" />
</Grid>
</DataTemplate>
Hi,
I have an updated. Your suggestion does in fact address my problem. Previously the animation duration was always at the default value. But now I set it to 0 before I re-layout and restore to 500ms when I want to show the first marker.
I had always assume that it was my introduction of animation of the text and image, which was triggered by the step progress bar, as opposed to it being the animation of the progress bar marker itself.
Thanks for your help!
Paul
Hi Paul,
We are glad to know that your issue is resolved. Please reach out to us if you need any further assistance.
Regards,
Yathavakrishnan M
Unfortunately it seems I was a bit premature, and although harder to cause the issue, I can still cause the issue. I am currently proving whether or not the issue ever occurs, if I leave this animation at 0.
If it doesn't, then we either need to decide to leave this disabled, or come up with a better solution (in terms of when I redefine the animation so we do see the marker display).
I'll post back when I can
We tried to reproduce the reported issue using the provided details, but we were unable to reproduce it. For your reference, we’ve attached the sample we used in an attempt to reproduce the issue. Could you please modify the attached sample to match your setup and share it back with us along with detailed replication steps? This will help us conduct a more thorough investigation.
Hi,
I spent quite some time producing a sample project that demonstrates the issue. I have tried to make this as brief as I could, but it needs to replicate the usage of my real application, This not the same codebase, but I am applying the same principles. Whilst I am not asking you to help debug my application, I will take on suggestions if you think I have not taken the correct approach. But I am sure you will agree that even if I am not doing this the best way, I should not be able to cause the SfStepProgressBar to indirectly raise this DoubleAnimation exception?
I think it important you understand how my real world application is attempting to use the progress bar:
_StampcardsList in the VM constructor. A timer is used to simulate selecting the first stampcard, 2 seconds after launch
The property StampcardIndex dictates which stampcard of those available should be current, and represented via the progress bar's layout
Disable animation
Load the StampStepsCollection (ItemSource for progress bar) via LoadStampcardAtIndex()
Restore animation
Select the appropriate SelectedStampIndex (SelectedIndex for progressbar)
Demonstration #2
In this demo, it is representative of a workaround I saw necessary to add to my end application. In this I use a timer to separate the loading of the collection driving the progress bar, and setting of the SelectedIndex to show the active markers (which actually are not currently looking correct in this sample, but I didn't want to get distracted with that)
Demonstration #1 In this demo, it is representative of what I want to do... disable animation (to avoid crash) while I redefine the ItemSource collection, then restore animation and set the active step
| We have reviewed the issue in the provided sample and the mentioned steps. The issue is occurring on the code side, not with the StepProgress bar. A call stack screenshot is attached for your reference. Please investigate the issue on your end. |
Demonstration #2
| We were able to reproduce the reported issue with the provided details on our end, and currently we are analyzing it. We will provide further details on February 13th, 2024 |
Hi,
Thanks for your prompt response. With regard to Demonstration #1, this is exactly the problem I expected.
If you when you had that call stack you had pressed the "Show External Code" button, you would see that whilst my code has modified a property, and raised OnPropertyChanged (that the SfStepProgressBar has it's SelectedIndex property bound to), the callstack shows the progress bar has attempted to start an animation when it was disabled
regards
Paul
Hi Paul,
With the provided details we could able to reproduce the demontration1 issue and as mentioned earlier we will check the above reported issues and update further details on February 13, 2025
Regards,
Yathavakrishnan M
We are still validating on this error details with high priority and will update further details on February 17, 2025.
Thank you. Whilst I would like to eliminate this issue from my customer experience, it is currently only on limited site trial and I don't consider it "high" priority so no need to rush it through. I do appreciate your consideration though.
Hi
Paul,
Upon further analysis, the issue occurred due to accessing the Progressbar
properties before the items source gets updated in the UI thread also before
changing the item resource. we need to reset all the properties. In the
provided sample we were reset the animation duration but SelectedStampIndex is
not reset so we request to set the SelectedStampIndex 0 before changing the
item recourse also we recommend to use dispatcher to update other properties of
the progreessbar after changing the item source. In order to avoid accessing
the progressbar before the item source get updated. Please refer to the code
snippet below.
|
private void LoadStampcardAtIndex(int index) { ProgressBarAnimationDuration = new TimeSpan(0); // Stop all animation
//Set SelectedStampIndex to 0 SelectedStampIndex = 0; StampStepsCollection = null; if ((index >= 0) && (index < _StampcardsList.Count)) { //SelectedStampIndex = -1;
StampStepsCollection = _StampcardsList[index].StampItems;
// Having switched the steps of the progress bar, I now want // to either make no markers active, or activate all those up // to the marker repesenting the no. of stamps they have.
#if USE_TIMER_FOR_DELAYED_MARKER //ProgressBarAnimationDuration = new TimeSpan(0, 0, 0, 0, 500); // Use default 500ms marker animation period Debug.WriteLine($"After loading stampcard, will set SelectedStampIndex to {_StampcardsList[index].NumStampsAchieved - 1}"); //However if I do this here, I get a DoubleAnimation exception!
Application.Current.Dispatcher.Invoke(() => { SelectedStampIndex = _StampcardsList[index].NumStampsAchieved - 1; }, System.Windows.Threading.DispatcherPriority.Render); #else // So instead, let's use a timer to do it very soon after Debug.WriteLine($"After loading stampcard, will set progress marker after timer delay..."); myMarkerTimer.Start();
#endif
// Space out stamp items depending on how many stamps are on the stampcard ResizeStampcardSpacingForThisManyStamps(_StampcardsList[_StampcardIndex].StampItems.Count);
// Refresh description of which stampcard is selected and how many stamps they have OnPropertyChanged(nameof(StampcardRecSummary)); } } |
Additionally, we have modified the sample you provided and attached it for your reference.
Regards,
Yathavakrishnan M
Hi, thanks for the update.
Interesting. I had also been "de-selecting" any marker in my own application (so as to ensure I see the animation on a new stampcard), though I had been setting the index to -1 to represent "nothing selected", in line with other collection based Syncfusion controls. After all, even if I have a marker at index 0, who's to say I want it to be represented as active? Or does there always have to be one active marker?
I added your suggested changes to my copy of the sample application and it did indeed appear to resolve it. No matter how quickly I clicked Prev/Next, I did not experience any exceptions. But I noted there was no animation as I had disabled it before switching stampcards, in line with previous advice here.
I though the most obvious thing would be to also do it via the dispatcher
Application.Current.Dispatcher.Invoke(() =>
{
ProgressBarAnimationDuration = new TimeSpan(0, 0, 0, 0, 500); // Use default 500ms period
SelectedStampIndex = _StampcardsList[index].NumStampsAchieved - 1;
}, System.Windows.Threading.DispatcherPriority.Render);
But although I now see an animation, it is possible to create the exception again by clicking Prev/Next fast.
Are you able to suggest a method of safely restoring animation, before the selected marker is set?
Thanks
Paul
Hi,
I didn't need to amend your sample. I just built it, ran it, and clicked fast. Please see my video attatched
regards
Paul
Hi Paul,
We have confirmed the issue “System.InvalidOperationException thrown while changing the animation of StepProgressBar continuously” as a defect in our product and we will include the fix for this issue in our Weekly NuGet Release which will be available on March 4, 2025.
Please use the below feedback link to track the status of the reported bug.
Note: If you require a patch for the reported issue in any of our Essential Studio Main or SP release version, then kindly let us know the version, so that we can provide a patch in that version based on our SLA policy.
Disclaimer: “Inclusion of this solution in the weekly release may change due to other factors including but not limited to QA checks and works reprioritization.”
Regards,
Yathavakrishnan M
We have included the fix for this “System.InvalidOperationException thrown while changing the animation of StepProgressBar continuously” in our latest weekly release (28.2.9). Upgrade to the latest version, to get the issue resolved.
Root Cause:
StepProgressBar was not loaded properly when the ItemSource was continuously changed.
Please use the below link to download our latest NuGet,
Nuget Link:
NuGet Gallery | Syncfusion.SfProgressBar.WPF 28.2.9
Feedback link
Hi,
Thanks very much. I can confirm that your fix does appear to address the issue in my sample application. Please thank your developers.
Paul
Hi Paul,
Thanks for your response. You can get back to us if you need any further assistance.
Regards,
Yathavakrishnan M