【问题标题】:How to fix animation that appears to not be running while Button Click event is processing?如何修复在处理按钮单击事件时似乎未运行的动画?
【发布时间】:2021-10-08 10:25:15
【问题描述】:

我正在使用 C# WPF 和 Blend for Visual Studio 2019。 我有一个按钮,点击后会从 SQL Server 数据库中获取数据。

此外,该按钮在 Blend 中有一个动画,将运行旋转 OnPreviewMouseDown

但问题是当我单击按钮时,一瞬间动画正在运行,然后突然停止。

我认为这个问题是因为Click 事件上的按钮运行了一些代码,导致动画无法继续。

长话短说:在处理点击事件时,按钮的动画似乎不起作用。

在混合中 :

XAML:

<Window.Resources>
    <Storyboard x:Key="RotationBtn">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="Command4">
            <EasingDoubleKeyFrame KeyTime="0:0:1" Value="720"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</Window.Resources>
<Window.Triggers>
    <EventTrigger RoutedEvent="UIElement.PreviewMouseDown" SourceName="Command4">
        <BeginStoryboard x:Name="RotationBtn_BeginStoryboard" Storyboard="{StaticResource RotationBtn}"/>
    </EventTrigger>
</Window.Triggers>

<Grid>
    <Button x:Name="Command4" Content="Next Stage" Margin="599,406,304,84"   Width="130" Height="37" FontSize="8" Click="Command4_Click" Background="#FFDDDDDD" BorderBrush="{x:Null}" RenderTransformOrigin="0.5,0.5">
        <Button.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                    <SkewTransform/>
                        <RotateTransform/>
                            <TranslateTransform/>
            </TransformGroup>
        </Button.RenderTransform>
    </Button>
</Grid>

CS 代码:

private void Command4_Click(object sender, RoutedEventArgs e)
{
    var MyQuery = dbms.Database.SqlQuery<DB_Cust>("SELECT * FROM Customers").ToList();
}

我尝试了什么:

第一次尝试

private void Command4_Click(object sender, RoutedEventArgs e)
{
    Thread trd = new Thread(() =>
    {
        Dispatcher.Invoke((Action)(() =>
        {
            Storyboard sb = TryFindResource("RotationBtn") as Storyboard;
            Storyboard.SetTarget(sb, Command4 );
            sb.Begin();
        }));
    });
    var MyQuery = dbms.Database.SqlQuery<DB_Cust>("SELECT * FROM Customers").ToList();
}

第二次尝试

private void Command4_Click(object sender, RoutedEventArgs e)
{
    new Thread(() =>
    {
        App.Current.Dispatcher.Invoke((Action)delegate
        {
            Storyboard sb = TryFindResource("RotationBtn") as Storyboard;
            Storyboard.SetTarget(sb, Command4);
            sb.Begin();
        });
    }).Start();
    var MyQuery = dbms.Database.SqlQuery<DB_Cust>("SELECT * FROM Customers").ToList();
}

【问题讨论】:

  • 除了没有名为 RectangleSlider 的资源之外,运行一个立即调用 Dispatcher.Invoke 的 Thread 是没有意义的。直接启动 Storyboard 即可。
  • 对不起,我的问题说明中有错误我更新了我的问题仍然没有工作请再次检查

标签: c# wpf xaml blend


【解决方案1】:

首先,你忘记启动话题了:

        private void Command4_Click(object sender, RoutedEventArgs e)
        {

            Thread trd = new Thread(() =>
            {
                Dispatcher.Invoke((Action)(() =>
                {
                    Storyboard sb = TryFindResource("RotationBtn") as Storyboard;
                    Storyboard.SetTarget(sb, Command4);
                    sb.Begin();
                }));
            });
            trd.Start();
        }

其次,您的动画从旋转角度的当前值开始,一直持续到 720 度。
但是当您再次开始动画时,角度已经等于 720,并且动画到 720,因此不会发生。
要再次从零开始动画,您需要将第一帧设置为从零开始。

        <Storyboard x:Key="RotationBtn">
            <DoubleAnimationUsingKeyFrames
                Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"
                Storyboard.TargetName="Command4">
                <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="720"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>

但我宁愿使用具有相对位移的线性动画,而不是逐帧。
当然,如果这对您的任务是可以接受的。

        <Storyboard x:Key="RotationBtn">
            <DoubleAnimation
                Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"
                Storyboard.TargetName="Command4"
                By="720"/>
        </Storyboard>

第三, 类“Storyboard”、“BeginStoryboard”和其他类旨在使从 XAML 运行动画变得容易。
从 Sharpe 启动时,它们不是必需的。
当然,它们可以在 Sharpe 中使用,但这没有什么意义。

此外,在现代 Sharp 中,不接受显式创建新流程(仅在极少数情况下)。 任务用于异步执行。

<Window ---------------------------
        ---------------------------
        ---------------------------
        Height="600" Width="1700">
    <Window.Resources>
        <DoubleAnimation x:Key="Button.Rotate.Animation" By="720"/>
    </Window.Resources>
    <Grid>
        <Button x:Name="Command4" Content="Next Stage" Margin="599,406,304,84"
                Width="130" Height="37" FontSize="8" Click="Command4_Click"
                Background="#FFDDDDDD" BorderBrush="{x:Null}"
                RenderTransformOrigin="0.5,0.5">
            <Button.RenderTransform>
                <RotateTransform x:Name="ButtonRotate"/>
            </Button.RenderTransform>
        </Button>
    </Grid>
</Window>
        private void Command4_Click(object sender, RoutedEventArgs e)
        {

            Task.Run(() =>
            {
                Dispatcher.Invoke((Action)(() =>
                {
                    var animation = TryFindResource("Button.Rotate.Animation") as AnimationTimeline;
                    ButtonRotate.BeginAnimation(RotateTransform.AngleProperty, animation);
                }));
            });
        }

第四,您在点击器中分配了不必要的目标元素。
声明 StoryBoard 时,目标已在 XAML 中指定。 还要注意动画的双重调用。
第一次按下某个键时,会在 XAML 中调用触发器动画。
第二次释放按键时,点击器动画被调用。

    <Window.Resources>
        <Storyboard x:Key="RotationBtn">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Angle" Storyboard.TargetName="ButtonRotate">
                <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="720"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="UIElement.PreviewMouseDown" SourceName="Command4">
            <BeginStoryboard x:Name="RotationBtn_BeginStoryboard" Storyboard="{StaticResource RotationBtn}"/>
        </EventTrigger>
    </Window.Triggers>

    <Grid>

        <Button x:Name="Command4" Content="Next Stage"
                Margin="599,406,304,84" 
                Width="130" Height="37" FontSize="8"
                Click="Command4_Click" Background="#FFDDDDDD"
                BorderBrush="{x:Null}"
                RenderTransformOrigin="0.5,0.5">
            <Button.RenderTransform>
                <RotateTransform x:Name="ButtonRotate"/>
            </Button.RenderTransform>
        </Button>

    </Grid>
</Window>
        private void Command4_Click(object sender, RoutedEventArgs e)
        {
            new Thread(() =>
            {
                Dispatcher.Invoke((Action)delegate
                {
                    Storyboard sb = TryFindResource("RotationBtn") as Storyboard;
                    //Storyboard.SetTarget(sb, ButtonRotate);
                    sb.Begin();
                });
            }).Start();
        }

P.S.我没有看到你的“第二次尝试”。这是因为我的粗心。
我向你道歉。
但我的回答中的其余观点仍然相关。

【讨论】:

  • 谢谢我会尝试,但我该怎么办?! : 处理事件点击时按钮的动画不工作
  • 点击按钮后动画不工作
  • 我更新了我的问题
  • 我用第四点补充了我的答案。阅读它。
  • 在最后第四点,适用于我的代码。它的工作原理如下。按下按钮时,动画开始到 720 度。释放后,它会重新启动。如果释放按钮,在第一个动画完成之前,第二个动画会中断第一个动画并从零角度开始。随着反复的新闻和发布,一切都在重复。不会出现延迟、意外中断或关机。
【解决方案2】:

试试这个:

 private void Command4_Click(object sender, RoutedEventArgs e)
        {
BackgroundWorker bgWorker = new BackgroundWorker ();
bgWorker.DoWorker += DoWorkEventHandler(bgWorker_DoWork);
        }
Private void bgWorker_DoWork(object sender, DoWorkEvent)
{
 Storyboard sb = TryFindResource("RotationBtn") as Storyboard;
                    //Storyboard.SetTarget(sb, ButtonRotate);
                    sb.Begin();
}

【讨论】:

  • 它不工作梗塞线程不工作
猜你喜欢
  • 2010-09-10
  • 2011-10-16
  • 2014-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-27
相关资源
最近更新 更多