Приложение WPF DispatcherTimer работает неправильно (задержка) - PullRequest
0 голосов
/ 17 октября 2018

Я пытался запустить очень простое приложение, которое каждую секунду перемещает квадрат 20 на 20 пикселей на 20 пикселей вправо на холсте.Я использую диспетчер для запуска события каждую секунду.

Проблема в том, что квадрат не сдвигается вправо, если я не встряхиваю окно приложения (с помощью мыши), и он иногда перемещается сам по себе(хотя и не каждую секунду).

Я уже пытался переустановить Visual Studio 2017 и установить его на мой SSD и жесткий диск, но ни одна из них, похоже, не устранила проблему.

Вот полный код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»

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Вы можете попробовать установить DispatcherPriority в Normal.

Создайте свой таймер следующим образом:

DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Normal);

РЕДАКТИРОВАТЬ:

Хотя это каким-то образом решило проблему (квадрат двигался без необходимости перемещать окно), это по-прежнему неправильный ответ.Я не знаю много о DispatcherTimer, но я помню, что однажды изменил приоритет, но я не помню почему.В любом случае, это может быть полезно для кого-то еще.

0 голосов
/ 17 октября 2018

Вам не нужно удалять и добавлять прямоугольник на каждом таймере таймера или каждый раз сбрасывать его свойства.

Просто увеличивайте значение свойства 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);
}
...