Search code examples
c#wpfxamlanimationcoloranimation

Exception animating Label's Foreground: Cannot animate '(0).(1)' on a hard object instance


I have an ItemsControl with a Label as ItemTemplate, when I run the application without the StoryBoard everything works just well. The problem comes when I try to animate the label's foreground, I get an exception that says "Cannot animate '(0).(1)' on a hard object instance" refering to (Label.Foreground).(SolidColorBrush.Color).

<ItemsControl ItemsSource="{Binding StatusList}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Columns="{Binding StatusList.Count}" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Label Content="{Binding Text}">
                            <Label.Style>
                                <Style TargetType="Label">
                                    <Setter Property="FontSize" Value="24"></Setter>
                                    <Setter Property="FontWeight" Value="Bold"></Setter>
                                    <Setter Property="HorizontalAlignment" Value="Center"></Setter>
                                    <Setter Property="VerticalAlignment" Value="Center"></Setter>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding IsOnError}" Value="False">
                                            <Setter Property="Foreground" Value="#33AA33"></Setter>
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding IsOnError}" Value="True">
                                            <Setter Property="Foreground" Value="Red" />
                                            <Setter Property="FontWeight" Value="Bold" />
                                            <DataTrigger.EnterActions>
                                                <BeginStoryboard>
                                                    <Storyboard>
                                                        <ColorAnimation
                                                            Storyboard.TargetProperty="(Label.Foreground).(SolidColorBrush.Color)"
                                                            RepeatBehavior="Forever"
                                                            AutoReverse="True" From="Red" To="Black" Duration="0:0:0.5">
                                                        </ColorAnimation>
                                                    </Storyboard>
                                                </BeginStoryboard>
                                            </DataTrigger.EnterActions>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Label.Style>
                        </Label>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

If I create this label outside the ItemsControl as a new control in the window with it's own bindings, the animation works well.

I also looked to others questions with this problem around here but non of the solutions worked for me, I think that it's because I'm working inside ItemsControl

Edit: I'm working with Caliburn Micro, although I don't think it has anything to do with it


Solution

  • You may run the animation from a DataTrigger in the DataTemplate's Triggers collection as shown below.

    Please note that it is not necessary to set the Foreground property to Red when you immediately run an animation that starts from Red.

    Instead of re-setting the Foreground property in a second DataTrigger, use StopStoryboard in the DataTrigger's ExitAction.

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Label x:Name="label"
                Content="{Binding Text}"
                Foreground="#33AA33"
                FontSize="24"
                FontWeight="Bold"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"/>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding IsOnError}" Value="True">
                    <DataTrigger.EnterActions>
                        <BeginStoryboard x:Name="labelAnimation">
                            <Storyboard>
                                <ColorAnimation
                                    Storyboard.TargetName="label"
                                    Storyboard.TargetProperty="Foreground.Color"
                                    RepeatBehavior="Forever"
                                    AutoReverse="True"
                                    From="Red" To="Black"
                                    Duration="0:0:0.5"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.EnterActions>
                    <DataTrigger.ExitActions>
                        <StopStoryboard BeginStoryboardName="labelAnimation"/>
                    </DataTrigger.ExitActions>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ItemsControl.ItemTemplate>