c# - 无法让线程和动画旋转工作
问题描述
这是我的控制:
我正在使用以下代码旋转它:
全局变量,bool IsTriangleAnimRunning = false;
其余代码:
public void AnimateTriangle()
{
var rotation = (int)((100 / 100d) * 45 * 1); // Max 45 degree rotation
var duration = (int)(750 * (100 / 100d)); // Max 750ms rotation
while (IsTriangleAnimRunning != false)
{
MyTriangle.Dispatcher.BeginInvoke(
(Action)(() =>
{
var anim = new DoubleAnimation
{
To = rotation,
Duration = new Duration(TimeSpan.FromMilliseconds(duration)),
AutoReverse = true
};
var rt = new RotateTransform();
MyTriangle.RenderTransform = rt;
rt.BeginAnimation(RotateTransform.AngleProperty, anim);
}), DispatcherPriority.ContextIdle);
Thread.Sleep(duration * 2);
}
}
触发动画的按钮的事件处理程序:
public void HandleTriangleEvents(object sender, RoutedEventArgs a)
{
Thread t_triagle = new Thread(new ThreadStart(this.AnimateTriangle));
Button btn = (Button)sender;
if (btn.Name == "btnStartTriangleAnim")
{
IsTriangleAnimRunning = true;
btnStartTriangleAnim.IsEnabled = false;
t_triagle.Start();
}
else
{
IsTriangleAnimRunning = false;
btnStartTriangleAnim.IsEnabled = true;
t_triagle.Abort();
}
}
它的行为不自然,因为当我停止它时,它会重置为正常位置。我假设它出于某种原因这样做,我无法理解。此外,由于某种原因,此代码不会让它持续运行,而只会运行一次。
所需的功能: 如果,我点击开始按钮,运行线程并继续旋转,同时线程正在运行。如果,我打,停,然后停在当前的旋转状态。如果我点击开始,再次运行线程并继续来回旋转。
--
使用 Task Async 测试,运行速度较慢且不重复。
private async Task AnimateTriangle()
{
double rotation = 45d;
double duration = 100d;
var anim = new DoubleAnimation
{
To = rotation,
Duration = TimeSpan.FromMilliseconds(duration),
AutoReverse = true,
RepeatBehavior = RepeatBehavior.Forever
};
var transform = MyTriangle.RenderTransform as RotateTransform;
await Task.Factory.StartNew(() =>
{
while (IsTriangleAnimRunning != false)
{
MyTriangle.Dispatcher.Invoke(() =>
{
if (transform == null)
{
transform = new RotateTransform();
MyTriangle.RenderTransform = transform;
}
transform.BeginAnimation(RotateTransform.AngleProperty, anim);
}, DispatcherPriority.ContextIdle);
if (IsTriangleAnimRunning == false)
{
MyTriangle.Dispatcher.Invoke(() =>
{
if (MyTriangle.RenderTransform is RotateTransform)
{
var angle = transform.Angle; // current animated value
transform.Angle = angle;
transform.BeginAnimation(RotateTransform.AngleProperty, null);
}
}, DispatcherPriority.ContextIdle);
}
}
});
}
解决方案
您不需要启动线程。
启动一个永远运行的动画,直到你通过设置一个null
动画来重置它。
在重置它之前,将目标属性的值显式设置为当前动画值。
重复使用现有的 RotateTransform,而不是在每次启动动画时重新分配一个。
private void StartButtonClick(object sender, RoutedEventArgs e)
{
double rotation = 45d;
double duration = 750d;
var anim = new DoubleAnimation
{
To = rotation,
Duration = TimeSpan.FromMilliseconds(duration),
AutoReverse = true,
RepeatBehavior = RepeatBehavior.Forever
};
var transform = MyTriangle.RenderTransform as RotateTransform;
if (transform == null)
{
transform = new RotateTransform();
MyTriangle.RenderTransform = transform;
}
transform.Angle = 0d;
transform.BeginAnimation(RotateTransform.AngleProperty, anim);
}
private void StopButtonClick(object sender, RoutedEventArgs e)
{
if (MyTriangle.RenderTransform is RotateTransform transform)
{
var angle = transform.Angle; // current animated value
transform.Angle = angle;
transform.BeginAnimation(RotateTransform.AngleProperty, null);
}
}
推荐阅读
- javascript - React,如何在组件外部单击时向输入框提交更新
- c++ - C++ 中的 Realloc 指针,在 C 中是 malloced()
- odoo - 没有名为 web_kanban Odoo V11 的模块
- c# - 检查字典中是否存在键
- laravel - 为什么我不断收到错误 419 页面已过期
- django - AttributeError: 'WSGIRequest' 对象没有属性 'site' - wagtail, wagalytics
- android - 使用子字符串函数在 Android 中运行 SQL 查询时出错
- vba - 访问查询运行主表
- vue.js - vue-chartjs - 经验丰富的 Vue 开发人员是否使用此包装器?
- c# - C# 调用一个 DLL 函数,该函数返回一个指向结构数组的指针的指针