【发布时间】:2021-07-06 06:19:12
【问题描述】:
我目前正在开发一个程序,我想使用 Dispatcher Timer 自动移动一个椭圆。只要我的鼠标静止不动,它就可以正常工作。但是,当我开始移动鼠标时,椭圆移动得非常慢,甚至完全停止移动。当停止移动它时,程序再次正常运行。椭圆是 Canvas 的 Child,背景中除此 Canvas 外没有其他 UI 元素。我也没有在画布上添加任何事件。 我的目标是,将鼠标移到应用程序上,而不影响动画。 有人对解决这个问题有什么建议吗? 先感谢您! 蔚蓝
这是一个最小可重现示例的所有代码: Xaml.cs:
public partial class MainWindow : Window
{
public DispatcherTimer timer = new DispatcherTimer();
public MainWindow()
{
InitializeComponent();
Canvas.SetLeft(Ball, 0);
Canvas.SetTop(Ball, 225);
timer.Interval = TimeSpan.FromMilliseconds(4.16666666);
timer.Tick += Move;
timer.Start();
}
private void Move(object sender, EventArgs e)
{
if ((MapCanvas.ActualWidth - Ball.Width) > Canvas.GetLeft(Ball))
{
Canvas.SetLeft(Ball, Canvas.GetLeft(Ball) + 2);
}
}
}
这里是 xaml:
<Window x:Class="BallSpielExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BallSpielExample"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Canvas x:Name="MapCanvas" Background="NavajoWhite" Width="auto" Height="auto">
<Ellipse Name="Ball" Width="30" Height="30" Fill="SaddleBrown"/>
</Canvas>
</Grid>
【问题讨论】:
-
您最好创建一个minimal reproducible example 并将其包含在您的问题中,这样我们就不必猜测您的虚构代码存在哪些问题。
-
好的,谢谢,我正在努力。
-
DispatcherTimer与其他Dispatcher操作在同一线程上执行。检查设置不同的DispatcherPriority(DispatcherTimer的构造函数之一的参数)是否会有所帮助。如果没有,请考虑改用System.Timers.Timer- 它在单独的线程上运行(您必须使用Invoke或BeginInvoke从其Elapsed事件更新GUI)。 docs.microsoft.com/en-us/dotnet/api/… -
我认为您没有充分利用 wpf 中的动画。尝试双动画
-
绝对可以使用 DispatcherTimer 而不是 CompositionTarget.Rendering 或一些动画。您只需要确保时间间隔足够大,例如30-50 毫秒,并且您以与接受的答案中所示类似的方式确定自上次 Tick 处理程序调用以来经过的时间。可选地通过 DateTime.Now 而不是秒表。