WPF绑定Foreground动画时抛出异常的解决方案咨询
问题解决:WPF动画无法修改冻结画笔的错误
错误原因
当IsMonitoringButtonActive == false时,转换器返回的SolidColorBrush会被WPF自动冻结(性能优化机制),冻结后的对象处于不可变状态,导致ColorAnimation无法修改其Color属性,触发Cannot animate 'Foreground.(0)' on an immutable object instance错误。
解决方案
方案1:修改转换器,返回非冻结的画笔
在转换器创建画笔后,手动禁用冻结,确保画笔处于可变状态:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var brush = (bool)value ? new SolidColorBrush(Color.FromRgb(0, 255, 161)) : new SolidColorBrush(Color.FromRgb(131, 131, 131)); brush.Freeze(false); // 禁用自动冻结,允许动画修改属性 return brush; }
方案2:预先定义非冻结的画笔资源
在XAML资源中定义两个非冻结的画笔,让转换器直接返回这些实例:
<!-- 在ResourceDictionary或Window/UserControl的Resources中添加 --> <SolidColorBrush x:Key="MonitoringActiveBrush" Color="#00FFA1" IsFrozen="False"/> <SolidColorBrush x:Key="MonitoringInactiveBrush" Color="#838383" IsFrozen="False"/>
修改转换器:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var resourceKey = (bool)value ? "MonitoringActiveBrush" : "MonitoringInactiveBrush"; return Application.Current.Resources[resourceKey]; }
方案3:调整动画目标,直接动画Foreground属性
如果不需要平滑颜色过渡,可以改用ObjectAnimationUsingKeyFrames切换Foreground的画笔实例,避免修改冻结画笔的属性:
<Style x:Key="AlarmAnimation"> <Style.Triggers> <DataTrigger Binding="{Binding IsAlarmForMonitoringButton}" Value="True"> <DataTrigger.EnterActions> <BeginStoryboard> <Storyboard> <ObjectAnimationUsingKeyFrames AutoReverse="True" RepeatBehavior="Forever" Storyboard.TargetProperty="Foreground" Duration="0:0:0.5"> <DiscreteObjectKeyFrame KeyTime="0" Value="{Binding IsMonitoringButtonActive, Converter={StaticResource IsSelectedToColorConverter}}"/> <DiscreteObjectKeyFrame KeyTime="0:0:0.25" Value="Red"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </DataTrigger.EnterActions> </DataTrigger> </Style.Triggers> </Style>
推荐方案
优先选择方案1,改动最小,只需修改转换器即可解决问题,同时保留平滑的颜色过渡效果。
内容的提问来源于stack exchange,提问作者Lasoty
相关产品推荐
相关产品推荐

