WPF应用程序DispatcherTimer无法正常运行(滞后)

时间:2018-10-17 14:35:16

标签: c# wpf lag dispatchertimer

我一直在尝试运行一个非常简单的应用程序,该应用程序每秒将20 x 20像素正方形20像素向右移动到画布上。我正在使用调度程序计时器来每秒触发一次事件。

问题在于,除非我用鼠标摇动应用程序窗口,否则正方形不会向右移动,并且偶尔会移动(尽管不是每秒)。

我已经尝试过重新安装Visual Studio 2017并将其安装在我的SSD和HDD上,似乎都无法解决问题。

这是应用程序MainWindow.xaml.cs的完整代码

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    DispatcherTimer timer = new DispatcherTimer();
    Rectangle s = new Rectangle();
    Point currentPosition = new Point(20, 20);

    public MainWindow()
    {
        InitializeComponent();
        timer.Tick += Timer_Tick;
        timer.Interval = TimeSpan.FromSeconds(1);
        timer.Start();

        s.Width = 20;
        s.Height = 20;
        s.Fill = new SolidColorBrush(Colors.Black);

        map.Children.Add(s);
    }

    public void Timer_Tick(object sender, EventArgs e)
    {
        RedrawSquare(); 
    }

    public void RedrawSquare()
    {
        map.Children.Clear();

        s.Width = 20;
        s.Height = 20;
        s.Fill = new SolidColorBrush(Colors.Black);

        Canvas.SetLeft(s, currentPosition.X += 20);

        map.Children.Add(s);
    }
}

在MainWindow.xaml文件中,有一个名为“ map”的空Canvas

提前谢谢

2 个答案:

答案 0 :(得分:2)

您无需在每个计时器刻度上删除并添加矩形,也不必每次都重置其属性。

只需增加Canvas.Left属性的值即可:

public partial class MainWindow : Window
{
    private readonly DispatcherTimer timer = new DispatcherTimer();
    private readonly Rectangle s = new Rectangle();

    public MainWindow()
    {
        InitializeComponent();

        timer.Tick += Timer_Tick;
        timer.Interval = TimeSpan.FromSeconds(1);
        timer.Start();

        s.Width = 20;
        s.Height = 20;
        s.Fill = Brushes.Black;
        Canvas.SetLeft(s, 0);

        map.Children.Add(s);
    }

    public void Timer_Tick(object sender, EventArgs e)
    {
        Canvas.SetLeft(s, Canvas.GetLeft(s) + 20);
    }
}

使用动画可以使运动更加流畅

public MainWindow()
{
    InitializeComponent();

    s.Width = 20;
    s.Height = 20;
    s.Fill = Brushes.Black;
    Canvas.SetLeft(s, 0);

    map.Children.Add(s);

    var animation = new DoubleAnimation
    {
        By = 20,
        Duration = TimeSpan.FromSeconds(1),
        IsCumulative = true,
        RepeatBehavior = RepeatBehavior.Forever
    };

    s.BeginAnimation(Canvas.LeftProperty, animation);
}

答案 1 :(得分:-1)

您可以尝试将DispatcherPriority设置为Normal

像这样实例化计时器:

DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Normal);

编辑:

尽管这以某种方式解决了该问题(正方形无需移动窗口即可移动),但显然仍然是错误的答案。我对DispatcherTimer不太了解,但是我记得曾经改变过一次优先级,但是我不记得为什么。无论如何,这可能对其他人有帮助。