2011-04-11 69 views
7

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

我认为问题在于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; 
    } 

回答

1

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

/*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; 
    } 
7

定义故事板作为一个静态资源,

<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(); 
} 
+0

你测试了吗? 'StaticResources'?你的意思是“资源”吗?那么'x:Key'呢? – 2011-04-11 15:38:26

+0

我测试了一个可以工作的示例代码,但我目前的真实代码太冗长了,所以我正在寻找替代品 – PawanS 2011-04-11 15:41:13

+0

@ H.B。对不起,现在无法测试此代码。你对StaticResources是正确的,它应该是'资源',我现在就改变它。 x:Key; 'x:'部分是可选的 – 2011-04-11 15:44:47

3

我解决这个问题用故事板类的Stop()方法这样

myStoryBoard.Stop(this.LayoutRoot); 

与此解决方案,您不必在资源申报故事板。

+1

为了做到这一点,当您启动动画时,您必须将第二个参数设置为true:开始(DependencyObject ...,allowsMo​​dification)。 – Sonhja 2014-11-14 12:14:40