You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ItemsControl内Label前景色动画异常:无法在硬对象实例上执行动画

问题:ItemsControl中Label前景色动画抛出异常

在使用ItemsControl并以Label作为ItemTemplate时,未添加StoryBoard程序运行正常,但为Label前景色添加动画时,抛出异常Cannot animate '(0).(1)' on a hard object instance,异常指向(Label.Foreground).(SolidColorBrush.Color)。单独在窗口中创建该Label并绑定数据时,动画可正常运行,推测问题出在ItemsControl内的操作。使用Caliburn Micro框架,但判断与此问题无关。

相关XAML代码:

<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>
解决方案

异常核心原因:在Style的Setter中直接使用Red这类颜色字面量时,WPF会复用冻结的SolidColorBrush实例(冻结对象不可修改,而动画需要修改对象属性,因此触发报错)。单独使用Label时,WPF创建的是非冻结实例,所以动画能正常运行。

修复步骤:

  1. 定义非冻结的SolidColorBrush资源,避免WPF复用冻结实例
  2. 修改Style中Foreground的Setter,引用自定义Brush资源
  3. 简化动画的TargetProperty路径(Style已指定TargetType为Label,可省略Label前缀)

修改后的代码示例:

<Window.Resources>
    <SolidColorBrush x:Key="ErrorForegroundBrush" Color="Red" IsFrozen="False" />
    <SolidColorBrush x:Key="NormalForegroundBrush" Color="#33AA33" IsFrozen="False" />
</Window.Resources>

<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 Property="FontWeight" Value="Bold"/>
                        <Setter Property="HorizontalAlignment" Value="Center"/>
                        <Setter Property="VerticalAlignment" Value="Center"/>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding IsOnError}" Value="False">
                                <Setter Property="Foreground" Value="{StaticResource NormalForegroundBrush}"/>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding IsOnError}" Value="True">
                                <Setter Property="Foreground" Value="{StaticResource ErrorForegroundBrush}" />
                                <Setter Property="FontWeight" Value="Bold" />
                                <DataTrigger.EnterActions>
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ColorAnimation
                                                Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)"
                                                RepeatBehavior="Forever"
                                                AutoReverse="True" 
                                                From="Red" 
                                                To="Black" 
                                                Duration="0:0:0.5"/>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </DataTrigger.EnterActions>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Label.Style>
            </Label>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

补充说明:

  • 设置IsFrozen="False"确保Brush实例可被动画修改
  • 也可以直接在Setter中创建新Brush实例(如<Setter Property="Foreground"><Setter.Value><SolidColorBrush Color="Red"/></Setter.Value></Setter>),但使用资源更便于复用维护

内容的提问来源于stack exchange,提问作者Quino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 19:47:48