【问题标题】:Stop WPF animation, storyboard begin in xaml but stopping it in codebehind?停止 WPF 动画,情节提要以 xaml 开始,但在代码隐藏中停止?
【发布时间】:2011-08-03 04:12:53
【问题描述】:

我在 xaml 文件中创建了一个动画故事板。该故事板从 Button.Click 开始。但是为了停止动画,我试图在后面的代码中停止我的自定义事件的情节提要。 代码没有抛出任何异常,但是当我的事件被触发时,动画仍然继续。

我认为问题在于 Stop 方法。停止需要与开始动画相同的对象来停止它。但是这里的故事板是从 WPF xaml 开始的,我在后面的代码中停止它。

任何解决方案,如何在代码中获取 Xaml 对象或任何替代解决方案?

XAML 代码:

<Canvas.Triggers>
            <EventTrigger RoutedEvent="Button.Click" SourceName="ScanButton">
                <EventTrigger.Actions>
                    <BeginStoryboard >
                        <Storyboard  Name="MovingServer" Storyboard.TargetName="ImageMove" RepeatBehavior="Forever" >
                            <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2" From="30" To="300" BeginTime="0:0:0" />
                            <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:5" From="300" To="300" BeginTime="0:0:5" />
                            <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2" From="300" To="600" BeginTime="0:0:7" />
                            <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:2" From="1" To="0" BeginTime="0:0:7" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger.Actions>
            </EventTrigger>

代码隐藏:

    private void EventPublisher_OnScanningFinish(object sender, EventArgs args)
    {
        Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate() { this.StopScanningAnimation(); });
    }

    private void StopScanningAnimation()
    {

        ServerView.StoryBoardServerScrolling.Stop(this); //---------- Not Working

        //this.ServerView.Server1Static.Visibility = System.Windows.Visibility.Hidden;
        //this.ServerView.Server2Static.Visibility = System.Windows.Visibility.Hidden;
        //this.ServerView.Server3Scrolling.Visibility = System.Windows.Visibility.Hidden;
        //this.ServerView.SearchingGlass.Visibility = System.Windows.Visibility.Hidden;
    }

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    将故事板定义为静态资源,

    <MyControl.Resources>
                            <Storyboard Key="MovingServer" Storyboard.TargetName="ImageMove" RepeatBehavior="Forever" >
                                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2" From="30" To="300" BeginTime="0:0:0" />
                                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:5" From="300" To="300" BeginTime="0:0:5" />
                                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2" From="300" To="600" BeginTime="0:0:7" />
                                <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:2" From="1" To="0" BeginTime="0:0:7" />
                            </Storyboard>
    </MyControl.Resources>
    

    并从您的后端代码中引用它,如下所示:

    StoryBoard board = (StoryBoard)this.FindResource("MovingServer");
    board.stop();
    

    从按钮的 'click' 事件开始动画(我不知道你是否在 xaml 中定义,但如果你这样做了,这里是如何完成的)

    <Button x:Name="ScanButton" onClick="Scanbutton_Click"></button>
    
    
    protected void Scanbutton_Click(object Sender, EventArgs e)
    {
        StoryBoard board = (StoryBoard)this.FindResource("MovingServer");
        board.start();
    }
    

    【讨论】:

    • 你测试过这个吗? StaticResources?你是说Resources吗? x:Key 呢?
    • 我测试了一个可以运行的示例代码,但是我当前的真实代码太长了,所以我正在寻找替代方案
    • @H.B.抱歉,目前无法测试此代码。您对 StaticResources 是正确的,它应该是“资源”,我现在就更改它。 x:键; 'x:' 部分是可选的
    • 只是为了指出您需要添加键而不是名称的事实。另外:我有同样的想法并尝试过,似乎也没有停止动画。
    • @我尝试使用 windows 资源...这不起作用... K 更新它
    【解决方案2】:

    我很感谢蒂莫西提出了很好的想法。我在这里发布我的工作代码

       /*create this resources as global to that perticular xaml. Need not to be put it in App.xaml
         MyControl could be Window or Page or UserControl */
    
           <MyControl.Resources>
            <Storyboard x:Key="MovingServer" Storyboard.TargetName="MyImage" RepeatBehavior="Forever" >
                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2" From="30" To="300" BeginTime="0:0:0" />
                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:5" From="300" To="300" BeginTime="0:0:5" />
                <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2" From="300" To="600" BeginTime="0:0:7" />
                <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:2" From="1" To="0" BeginTime="0:0:7" />
            </Storyboard>
        </MyControl.Resources>
    
    /* <!-- Now use those animation resources, the place where you want. You can use it as static resource and begin stop animation from code behind OR use it as trigger event --> */
    
    /*    <!-- Static resources--> */
        <Canvas>
            <Image Canvas.Left="0" Canvas.Top="-2" Height="32" Name="MyImage" Width="32" Source="/CCTrayHelper;component/Images/ServerIcon.png" Visibility="Hidden"/>
         <Canvas.Resources>
            <BeginStoryboard x:Key="serverAnimate" Storyboard="{StaticResource MovingServer}" />
         </Canvas.Resources>
        </Canvas>
        <Button x:Name="ScanButton" onClick="Scanbutton_Click" />
    
    /* ****************************************************************** */
    
    
    
      /*  Code behind to start/stop animation*/
    
    //Get the resource value first on current object, so that when you start/stop the animation, it work only on current object
      Storyboard sbImageAnimate = (Storyboard)this.ServerView.FindResource("MovingServer");
    
    //Start the animation on Button Click 
     protected void Scanbutton_Click(object Sender, EventArgs e)
      {   
       this.MyImage.Visibility = System.Windows.Visibility.Visible; 
       sbImageAnimate.Begin();
      } 
    
     //Stop animation on my own even. You can use it on any event
     private void EventPublisher_OnFinish(object sender, EventArgs args) 
     {   
          Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate() { this.StopScanningAnimation(); });  
     }
    
     private void StopScanningAnimation()  
       {
       sbImageAnimate.Stop();
       this.MyImage.Visibility = System.Windows.Visibility.Hidden; 
       } 
    

    【讨论】:

      【解决方案3】:

      我用这样的 Storyboard 类的Stop() 方法解决了这个问题

      myStoryBoard.Stop(this.LayoutRoot);
      

      使用此解决方案,您不必在资源中声明 Storyboard。

      【讨论】:

      • 如果能够这样做,当你开始动画时你必须将第二个参数设置为true:Begin(DependencyObject...,allowsMo​​dification)。
      猜你喜欢
      • 1970-01-01
      • 2020-08-06
      • 1970-01-01
      • 2014-04-16
      • 2011-07-31
      • 1970-01-01
      • 2017-02-17
      • 2013-05-19
      • 2011-01-01
      相关资源
      最近更新 更多