WPF控件:如何在动画中引用资源?

WPF控件:如何在动画中引用资源?,wpf,wpf-controls,styles,storyboard,Wpf,Wpf Controls,Styles,Storyboard,我已经编写了一个控件并成功创建了一个故事板,以便在触发事件期间生成动画。它会在一段时间内更改椭圆的填充。每次需要更改填充时,我都不会编写一个新的RadialGradientBrush,而是在参考资料中提供了其中两个 编辑: 我有一个椭圆,它是控件的主要组件,受动画的影响。它的实现非常简单,如下所示: <Ellipse Name="myEllipse" Style="{StaticResource DimStyle}" /> <DiscreteObjectKeyFrame Ke

我已经编写了一个控件并成功创建了一个故事板,以便在触发事件期间生成动画。它会在一段时间内更改椭圆的填充。每次需要更改填充时,我都不会编写一个新的
RadialGradientBrush
,而是在参考资料中提供了其中两个

编辑: 我有一个
椭圆
,它是控件的主要组件,受动画的影响。它的实现非常简单,如下所示:

<Ellipse Name="myEllipse" Style="{StaticResource DimStyle}" />
<DiscreteObjectKeyFrame KeyTime="0:0:0.01" Value="{StaticResource IlluminatedBrush}" />
<DiscreteObjectKeyFrame KeyTime="0:0:0.85" Value="{StaticResource DimBrush}" />
样式完全相同,只有
GradientStop
颜色属性不同,因此我将仅提供一种样式作为示例

引用的样式

<UserControl.Resources>
    <Style x:Key="IlluminatedStyle" TargetType="Ellipse">
        <Setter Property="Fill">
            <Setter.Value>
                <RadialGradientBrush>
                    <GradientStop Color="#FF215416" Offset="1"/>
                    <GradientStop Color="#FE38DA2E" Offset="0"/>
                    <GradientStop Color="#FE81FF79" Offset="0.688"/>
                </RadialGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

无法冻结
Freezable
的原因有三个:

  • 它具有动画或数据绑定属性
  • 它具有由动态资源设置的属性
  • 它包含无法冻结的可冻结子对象

因此,首先找出哪个
Freezable
引起了问题,然后检查上面的内容。

看到我是WPF和XAML新手,我犯了一个错误,将我的资源作为一种样式,并没有意识到我可以简单地将画笔作为一种资源,完全避免使用样式

我将对
DiscreteObjectKeyFrame
s'值的引用保持为新笔刷资源的静态引用。我将椭圆改为:

<Ellipse Name="myEllipse" Fill="{StaticResource DimBrush" />
我的资源更简单,没有被包装在一个风格和IMO,更优雅。在我的最终解决方案中,笔刷也是在动画之前定义的

<UserControl.Resources>
    <RadialGradientBrush x:Key="DimBrush" >
        <GradientStop Color="#FF21471A" Offset="1"/>
        <GradientStop Color="#FF33802F" Offset="0"/>
        <GradientStop Color="#FF35932F" Offset="0.688"/>
    </RadialGradientBrush>
    <RadialGradientBrush x:Key="IlluminatedBrush">
        <GradientStop Color="#FF215416" Offset="1"/>
        <GradientStop Color="#FE38DA2E" Offset="0"/>
        <GradientStop Color="#FE81FF79" Offset="0.688"/>
    </RadialGradientBrush>
    <!-- Storyboard code follows... -->
</UserControl.Resources>


现在一切都按计划进行。我所能做的最好的假设是,样式是不可冻结的,因为它们是我删除的组件,并且我不再收到关于无法冻结的可冻结的组件的异常。

它们都在同一个UserControl.Resources中,但顺序如何?正在引用的资源(由StaticResource引用)必须位于引用它的资源之前。在资源中,样式位于它之后。这在WPF中很重要吗?我有点惊讶,因为我可以在CS文件中一个接一个地编写一个类,但仍然在顶级类中引用底层类并正确编译。顺序与StaticResources有关,而与DynamicResources无关。@Jon,我在DiscreteObjectKeyFrames中添加了stacktrace和KeyTime属性值@Wonko,在这种情况下使我的资源动态化是否理想?在调试器内运行应用程序,并在引发异常时查看哪个
Freezable
正是
GetCurrentValueAsFrozenCore
的参数(调用堆栈中的第三个)。您是这里使用调试器的人,请使用它。:-)感谢您提供的信息,我是WPF新手,非常感谢您的指导。考虑到这是一个引发该异常的故事板动画,我认为这是有意义的,但考虑到它将在我不将关键帧值作为样式引用时运行,这是没有意义的。也许我应该放弃代码重用,把这个放在一边。我不知道从哪里解决这个问题。我提出了一个解决方案,但无法调试您的请求。谢谢你。
<DiscreteObjectKeyFrame KeyTime="0:0:0.01" Value="{StaticResource IlluminatedBrush}" />
<DiscreteObjectKeyFrame KeyTime="0:0:0.85" Value="{StaticResource DimBrush}" />
<UserControl.Resources>
    <RadialGradientBrush x:Key="DimBrush" >
        <GradientStop Color="#FF21471A" Offset="1"/>
        <GradientStop Color="#FF33802F" Offset="0"/>
        <GradientStop Color="#FF35932F" Offset="0.688"/>
    </RadialGradientBrush>
    <RadialGradientBrush x:Key="IlluminatedBrush">
        <GradientStop Color="#FF215416" Offset="1"/>
        <GradientStop Color="#FE38DA2E" Offset="0"/>
        <GradientStop Color="#FE81FF79" Offset="0.688"/>
    </RadialGradientBrush>
    <!-- Storyboard code follows... -->
</UserControl.Resources>