C# 故事板。Seek不';不影响

C# 故事板。Seek不';不影响,c#,wpf,animation,storyboard,wpf-4.0,C#,Wpf,Animation,Storyboard,Wpf 4.0,我正在WPF中创建一个自定义控件,它实际上是一个模拟时钟。这是一个非常简单的类,其模板如下所示: public class AnalogClock { public static readonly DependencyProperty AnimatorProperty = DependencyProperty.Register("Animator", typeof(Storyboard), typeof(AnalogClock), new Framewo

我正在
WPF
中创建一个自定义控件,它实际上是一个
模拟时钟。这是一个非常简单的类,其模板如下所示:

public class AnalogClock {

    public static readonly DependencyProperty AnimatorProperty
        = DependencyProperty.Register("Animator", typeof(Storyboard), typeof(AnalogClock),
        new FrameworkPropertyMetadata(null));

    public Storyboard Animator {
        get { return (Storyboard)GetValue(AnimatorProperty); }
        set { SetValue(AnimatorProperty, value); }
    }

    public override void OnApplyTemplate() {
        base.OnApplyTemplate();
        if (Animator == null)
            return;

        ApplyTargetToTimeline("PART_HourHandAnimator", "PART_HourHand");

        ApplyTargetToTimeline("PART_MinuteHandAnimator", "PART_MinuteHand");

        ApplyTargetToTimeline("PART_SecondHandAnimator", "PART_SecondHand");

        ApplyTargetToTimeline("PART_IconAnimator", "PART_Icon");

        Animator.Begin(this, Template);
        // try to seek the timeline, to DateTime.Now.TimeOfDay
        // but can not ):
        Animator.Seek(this, DateTime.Now.TimeOfDay, TimeSeekOrigin.Duration);
    }

    private void ApplyTargetToTimeline(string timelineName, string targetName) {
        var timeline = Animator.Children.FirstOrDefault(t => t.Name == timelineName);
        if (timeline == null)
            throw new InvalidOperationException(string.Format(
                "The Timeline named '{0}' could not be found.", timelineName));
        Storyboard.SetTargetName(timeline, targetName);
    }
}
下面是
XAML

情节提要资源:

<Storyboard x:Key="Animator">

    <DoubleAnimation x:Name="PART_HourHandAnimator" From="0" To="360" Duration="12:00:00" BeginTime="00:00:00.000000"
                     RepeatBehavior="Forever" Storyboard.TargetName="{Binding}" Storyboard.Target="{Binding}"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation x:Name="PART_MinuteHandAnimator" From="0" To="360" Duration="1:00:00" BeginTime="00:00:00.000000"
                     RepeatBehavior="Forever" Storyboard.TargetName="{Binding}" Storyboard.Target="{Binding}"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation x:Name="PART_SecondHandAnimator" From="0" To="360" Duration="00:01:00" BeginTime="00:00:00.000000"
                     RepeatBehavior="Forever" Storyboard.TargetName="{Binding}" Storyboard.Target="{Binding}"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation x:Name="PART_IconAnimator" From="0" To="360" Duration="00:01:00" BeginTime="00:00:00.000000"
                     RepeatBehavior="Forever" Storyboard.TargetName="{Binding}" Storyboard.Target="{Binding}"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

</Storyboard>
<ControlTemplate x:Key="MyTemplate" TargetType="{x:Type ui:AnalogClock}">
    <Border>
        <Viewbox>
            <Grid>
                <Ellipse x:Name="PART_Icon" >
                    <Ellipse.RenderTransform>
                        <RotateTransform CenterX="25" CenterY="25" />
                    </Ellipse.RenderTransform>
                </Ellipse>
                <Grid>
                    <Canvas x:Name="PART_SecondHand">
                        <Ellipse RenderTransformOrigin="0.5,0.5"/>
                        <Canvas.RenderTransform>
                            <RotateTransform CenterX="60" CenterY="60"/>
                        </Canvas.RenderTransform>
                    </Canvas>
                    <Canvas>
                        <Path x:Name="PART_HourHand"  Fill="SomeBrush"
                              Data="Some data" RenderTransformOrigin="0.493,0.933">
                            <Path.RenderTransform>
                                <RotateTransform  />
                            </Path.RenderTransform>
                        </Path>
                        <Path x:Name="PART_MinuteHand"  Fill="Some brush"
                              Data="Some Data" RenderTransformOrigin="0.493,0.933">
                            <Path.RenderTransform>
                                <RotateTransform />
                            </Path.RenderTransform>
                        </Path>
                    </Canvas>
                </Grid>
            </Grid>
        </Viewbox>
    </Border>
</ControlTemplate>
<Style x:Key="MyClock" TargetType="{x:Type ui:AnalogClock}">
    <Setter Property="Animator" Value="{StaticResource Animator}"/>
    <Setter Property="Template" Value="{StaticResource MyTemplate}"/>
</Style>

模板:

<Storyboard x:Key="Animator">

    <DoubleAnimation x:Name="PART_HourHandAnimator" From="0" To="360" Duration="12:00:00" BeginTime="00:00:00.000000"
                     RepeatBehavior="Forever" Storyboard.TargetName="{Binding}" Storyboard.Target="{Binding}"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation x:Name="PART_MinuteHandAnimator" From="0" To="360" Duration="1:00:00" BeginTime="00:00:00.000000"
                     RepeatBehavior="Forever" Storyboard.TargetName="{Binding}" Storyboard.Target="{Binding}"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation x:Name="PART_SecondHandAnimator" From="0" To="360" Duration="00:01:00" BeginTime="00:00:00.000000"
                     RepeatBehavior="Forever" Storyboard.TargetName="{Binding}" Storyboard.Target="{Binding}"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation x:Name="PART_IconAnimator" From="0" To="360" Duration="00:01:00" BeginTime="00:00:00.000000"
                     RepeatBehavior="Forever" Storyboard.TargetName="{Binding}" Storyboard.Target="{Binding}"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

</Storyboard>
<ControlTemplate x:Key="MyTemplate" TargetType="{x:Type ui:AnalogClock}">
    <Border>
        <Viewbox>
            <Grid>
                <Ellipse x:Name="PART_Icon" >
                    <Ellipse.RenderTransform>
                        <RotateTransform CenterX="25" CenterY="25" />
                    </Ellipse.RenderTransform>
                </Ellipse>
                <Grid>
                    <Canvas x:Name="PART_SecondHand">
                        <Ellipse RenderTransformOrigin="0.5,0.5"/>
                        <Canvas.RenderTransform>
                            <RotateTransform CenterX="60" CenterY="60"/>
                        </Canvas.RenderTransform>
                    </Canvas>
                    <Canvas>
                        <Path x:Name="PART_HourHand"  Fill="SomeBrush"
                              Data="Some data" RenderTransformOrigin="0.493,0.933">
                            <Path.RenderTransform>
                                <RotateTransform  />
                            </Path.RenderTransform>
                        </Path>
                        <Path x:Name="PART_MinuteHand"  Fill="Some brush"
                              Data="Some Data" RenderTransformOrigin="0.493,0.933">
                            <Path.RenderTransform>
                                <RotateTransform />
                            </Path.RenderTransform>
                        </Path>
                    </Canvas>
                </Grid>
            </Grid>
        </Viewbox>
    </Border>
</ControlTemplate>
<Style x:Key="MyClock" TargetType="{x:Type ui:AnalogClock}">
    <Setter Property="Animator" Value="{StaticResource Animator}"/>
    <Setter Property="Template" Value="{StaticResource MyTemplate}"/>
</Style>

样式:

<Storyboard x:Key="Animator">

    <DoubleAnimation x:Name="PART_HourHandAnimator" From="0" To="360" Duration="12:00:00" BeginTime="00:00:00.000000"
                     RepeatBehavior="Forever" Storyboard.TargetName="{Binding}" Storyboard.Target="{Binding}"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation x:Name="PART_MinuteHandAnimator" From="0" To="360" Duration="1:00:00" BeginTime="00:00:00.000000"
                     RepeatBehavior="Forever" Storyboard.TargetName="{Binding}" Storyboard.Target="{Binding}"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation x:Name="PART_SecondHandAnimator" From="0" To="360" Duration="00:01:00" BeginTime="00:00:00.000000"
                     RepeatBehavior="Forever" Storyboard.TargetName="{Binding}" Storyboard.Target="{Binding}"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation x:Name="PART_IconAnimator" From="0" To="360" Duration="00:01:00" BeginTime="00:00:00.000000"
                     RepeatBehavior="Forever" Storyboard.TargetName="{Binding}" Storyboard.Target="{Binding}"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

</Storyboard>
<ControlTemplate x:Key="MyTemplate" TargetType="{x:Type ui:AnalogClock}">
    <Border>
        <Viewbox>
            <Grid>
                <Ellipse x:Name="PART_Icon" >
                    <Ellipse.RenderTransform>
                        <RotateTransform CenterX="25" CenterY="25" />
                    </Ellipse.RenderTransform>
                </Ellipse>
                <Grid>
                    <Canvas x:Name="PART_SecondHand">
                        <Ellipse RenderTransformOrigin="0.5,0.5"/>
                        <Canvas.RenderTransform>
                            <RotateTransform CenterX="60" CenterY="60"/>
                        </Canvas.RenderTransform>
                    </Canvas>
                    <Canvas>
                        <Path x:Name="PART_HourHand"  Fill="SomeBrush"
                              Data="Some data" RenderTransformOrigin="0.493,0.933">
                            <Path.RenderTransform>
                                <RotateTransform  />
                            </Path.RenderTransform>
                        </Path>
                        <Path x:Name="PART_MinuteHand"  Fill="Some brush"
                              Data="Some Data" RenderTransformOrigin="0.493,0.933">
                            <Path.RenderTransform>
                                <RotateTransform />
                            </Path.RenderTransform>
                        </Path>
                    </Canvas>
                </Grid>
            </Grid>
        </Viewbox>
    </Border>
</ControlTemplate>
<Style x:Key="MyClock" TargetType="{x:Type ui:AnalogClock}">
    <Setter Property="Animator" Value="{StaticResource Animator}"/>
    <Setter Property="Template" Value="{StaticResource MyTemplate}"/>
</Style>

正如你所看到的,这是一个非常简单的控件。好吧,除了
情节提要外,它工作得很好。Seek
方法根本不起作用。我的意思是,控件显示得很好,动画开始得和我想要的一样好,但是从零开始);我希望我能将所有时间线的位置设置为
DateTime.Now.TimeOfDay
,但我不能。我尝试了
TimeSeekOrigin.Duration
TimeSeekOrigin.BeginTime
。但它们都不起作用。你能帮我找到问题吗?提前谢谢

最后,我很幸运:)首先,当我们在
模板上开始
情节提要时,不需要设置目标名称。第二,为了使脚本生效,我们应该在脚本开始时使用
iscontrolable=true
参数。一起:

<Storyboard x:Key="Animator">

    <DoubleAnimation From="0" To="360" Duration="12:00:00"
                     RepeatBehavior="Forever" Storyboard.TargetName="PART_HourHand"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation From="0" To="360" Duration="1:00:00"
                     RepeatBehavior="Forever" Storyboard.TargetName="PART_MinuteHand"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation From="0" To="360" Duration="00:01:00"
                     RepeatBehavior="Forever" Storyboard.TargetName="PART_SecondHand"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation From="0" To="360" Duration="00:01:00"
                     RepeatBehavior="Forever" Storyboard.TargetName="PART_Icon"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

</Storyboard>
最后,我很幸运:)首先,当我们在
模板上开始
情节提要时,不需要设置目标名称。第二,为了使脚本生效,我们应该在脚本开始时使用
iscontrolable=true
参数。一起:

<Storyboard x:Key="Animator">

    <DoubleAnimation From="0" To="360" Duration="12:00:00"
                     RepeatBehavior="Forever" Storyboard.TargetName="PART_HourHand"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation From="0" To="360" Duration="1:00:00"
                     RepeatBehavior="Forever" Storyboard.TargetName="PART_MinuteHand"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation From="0" To="360" Duration="00:01:00"
                     RepeatBehavior="Forever" Storyboard.TargetName="PART_SecondHand"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

    <DoubleAnimation From="0" To="360" Duration="00:01:00"
                     RepeatBehavior="Forever" Storyboard.TargetName="PART_Icon"
                     Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"/>

</Storyboard>