我正在尝试实现一个自定义IEasingFunction
,它基本上是另一个的包装器,IEasingFunction
但它在动画的开头和结尾添加了一个暂停。我不希望它继承,EasingFunctionBase
因为在 PausingEasingFunction 上有一个 EasingMode 是没有意义的。无论您使用哪种模式,暂停都是相同的,并且被包装的模式可以自行指定其模式。
这是它的外观:PausingEasingFunction.cs
public class PausingEasingFunction : DependencyObject, IEasingFunction
{
public static readonly DependencyProperty WrappedEasingFunctionProperty = DependencyProperty.Register(nameof(WrappedEasingFunction), typeof(IEasingFunction), typeof(PausingEasingFunction));
public static readonly DependencyProperty StartPauseProperty = DependencyProperty.Register(nameof(StartPause), typeof(double), typeof(PausingEasingFunction));
public static readonly DependencyProperty EndPauseProperty = DependencyProperty.Register(nameof(EndPause), typeof(double), typeof(PausingEasingFunction));
public IEasingFunction WrappedEasingFunction
{
get => (IEasingFunction)GetValue(WrappedEasingFunctionProperty);
set => SetValue(WrappedEasingFunctionProperty, value);
}
public double StartPause
{
get => (double)GetValue(StartPauseProperty);
set => SetValue(StartPauseProperty, value);
}
public double EndPause
{
get => (double)GetValue(EndPauseProperty);
set => SetValue(EndPauseProperty, value);
}
public double Ease(double normalizedTime)
{
if (normalizedTime < StartPause)
{
return 0;
}
else if (normalizedTime <= 1 - EndPause)
{
if (WrappedEasingFunction == null)
{
return (normalizedTime - StartPause) / (1 - StartPause - EndPause);
}
else
{
return WrappedEasingFunction.Ease((normalizedTime - StartPause) / (1 - StartPause - EndPause));
}
}
else
{
return 1;
}
}
}
问题是,当我尝试使用以下 xaml 在动画中使用它时(local:
指的是 xmlns 指向包含的 clr 命名空间PausingEasingFunction
):
<TextBlock Text="Hello I am some animated text!">
<TextBlock.RenderTransform>
<TranslateTransform X="0" x:Name="transform"/>
</TextBlock.RenderTransform>
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<BeginStoryboard.Storyboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="X" Storyboard.TargetName="transform" RepeatBehavior="Forever" From="0" To="100" Duration="0:0:10">
<DoubleAnimation.EasingFunction>
<local:PausingEasingFunction>
<local:PausingEasingFunction.WrappedEasingFunction>
<SineEase EasingMode="EaseInOut"/>
</local:PausingEasingFunction.WrappedEasingFunction>
</local:PausingEasingFunction>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard.Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
抛出 InvalidOperationException,告诉我无法冻结 Freezable。但是,如果我将PausingEasingFunction.cs更改为继承,Freezable
而不是通过DependencyObject
这种方式实现 CreateInstanceCore:
protected override Freezable CreateInstanceCore()
{
return new PausingEasingFunction();
}
不再抛出异常。经过一番调查,我发现 WPF 仍然试图冻结东西,即使它们有 CanFreeze = false 但我不确定这是否真的是问题所在......
这是一个WPF错误吗?难道我做错了什么?或者为什么我被迫从 Freezable 继承?