停止 WPF 动画,故事板从 xaml 开始,但在代码隐藏中停止?

发布于 2024-10-31 17:54:32 字数 2141 浏览 2 评论 0原文

我在 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;
    }

I created an animation storyboard in xaml file. That story board begins on Button.Click. But to stop the animation I am trying to stop storyboard on my custom event in code behind.
The code is not throwing any exception but When my event got fired the animation still goes continue.

I think the issue is with the Stop method. Stop required the same object that begins the animation to stop it. But here the storyboard is begin in WPF xaml and I am stopping it in code behind.

Any Solution, how to get Xaml object in code behind or Any alternative solution for this??

XAML CODE:

<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>

Code Behind:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

败给现实 2024-11-07 17:54:32

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

<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();

从按钮的“单击”事件启动动画(我不知道您是否在 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();
}

Define the storyboard as a static resource,

<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>

and reference it from your backend code as follows :

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

start the animation from the 'click' event of the button (i don't know if you defined in xaml, but here's how it would be done if you did)

<Button x:Name="ScanButton" onClick="Scanbutton_Click"></button>


protected void Scanbutton_Click(object Sender, EventArgs e)
{
    StoryBoard board = (StoryBoard)this.FindResource("MovingServer");
    board.start();
}
翻了热茶 2024-11-07 17:54:32

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

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

I am thankful for Timothy for giving nice Idea. Here I am posting my working code

   /*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; 
   } 
无尽的现实 2024-11-07 17:54:32

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

myStoryBoard.Stop(this.LayoutRoot);

您就不必在资源中声明 Storyboard。

I solve the problem with using the Stop() method of Storyboard class like this

myStoryBoard.Stop(this.LayoutRoot);

with this solution you don't have to declare Storyboard at the resource.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文