Intermittent Crash with Storyboard on RenderTransform
Posted: 17 Oct 2025, 15:20
Hi everyone,
I had a bug and I might have found a solution, but I'd like to understand if it's the "correct" or intended way to solve this, or if there's a cleaner approach or if the issue is still present.
I have a UserControl for a character sprite on a map. When I zoom the map in and out, I trigger a DataTrigger to animate the scale of the character. Most of the time it worked, but sometimes, especially during rapid zooming, the application would crash with an error like: "Can't resolve TargetProperty 'RenderTransform.ScaleX' in the specified target".
BEFORE
The Solution
After debugging, I found a solution that seems to work. I moved the entire visual structure into a <ControlTemplate>, gave the <ScaleTransform> an x:Name, and changed the Storyboard to target that name directly.
Here is the working code:
AFTER
My Question
This solution worksed for me. But it seems like a race condition where the animation trigger was firing before the RenderTransform property was set by the style.
Is this the standard, intended way to solve this kind of animation targeting issue in XAML? Or is there a cleaner, more direct way to do this without having to redefine the entire ControlTemplate?
Thanks for any insights!
I had a bug and I might have found a solution, but I'd like to understand if it's the "correct" or intended way to solve this, or if there's a cleaner approach or if the issue is still present.
I have a UserControl for a character sprite on a map. When I zoom the map in and out, I trigger a DataTrigger to animate the scale of the character. Most of the time it worked, but sometimes, especially during rapid zooming, the application would crash with an error like: "Can't resolve TargetProperty 'RenderTransform.ScaleX' in the specified target".
BEFORE
Code: Select all
<Button Command="{Binding SelectCharacterCommand}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="RenderTransformOrigin" Value="0.5, 0.5"/>
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.0" ScaleY="1.0" />
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding DataContext.IsDetailedView, RelativeSource={RelativeSource AncestorType=game:MapView}}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<!-- This path would sometimes fail -->
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="0.2" Duration="0:0:0.3"/>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" To="0.2" Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<!-- ... ExitActions ... -->
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
<!-- ... Content of the button ... -->
</Button>
After debugging, I found a solution that seems to work. I moved the entire visual structure into a <ControlTemplate>, gave the <ScaleTransform> an x:Name, and changed the Storyboard to target that name directly.
Here is the working code:
AFTER
Code: Select all
<Button Command="{Binding SelectCharacterCommand}">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid> <!-- Content is now inside the template -->
<Grid.RenderTransform>
<ScaleTransform x:Name="ButtonScaleTransform" ScaleX="1.0" ScaleY="1.0" />
</Grid.RenderTransform>
<Grid.RenderTransformOrigin>0.5, 0.5</Grid.RenderTransformOrigin>
<!-- ... All visual elements of the character sprite ... -->
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding DataContext.IsDetailedView, RelativeSource={RelativeSource AncestorType=game:MapView}}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<!-- Animation now targets the named element -->
<DoubleAnimation Storyboard.TargetName="ButtonScaleTransform" Storyboard.TargetProperty="ScaleX" To="0.2" Duration="0:0:0.3"/>
<DoubleAnimation Storyboard.TargetName="ButtonScaleTransform" Storyboard.TargetProperty="ScaleY" To="0.2" Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<!-- ... ExitActions ... -->
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
This solution worksed for me. But it seems like a race condition where the animation trigger was firing before the RenderTransform property was set by the style.
Is this the standard, intended way to solve this kind of animation targeting issue in XAML? Or is there a cleaner, more direct way to do this without having to redefine the entire ControlTemplate?
Thanks for any insights!