Reputation: 441
I have been trying to run a very simple application that moves a 20 by 20 pixel square 20 pixels to the right on a canvas every second. I am using a dispatchertimer to fire the event every second.
The problem is that the square doesn't move to the right unless I shake the application window (with my mouse), and it occasionally moves on its own (albeit not every second).
I have already tried reinstalling Visual Studio 2017 and installing it on my SSD and HDD, neither seem to fix the issue.
Here is the full code of the application's 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);
}
}
On the MainWindow.xaml file there is an empty Canvas with the name "map"
Thank you in advance
Upvotes: 0
Views: 2194
Reputation: 6907
You can try setting the DispatcherPriority to Normal
.
Instantiate your timer like this:
DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Normal);
EDIT:
Although this somehow fixed the issue (square was moving without the need to move the window), it's apparently still the wrong answer. I don't know much about the DispatcherTimer, but I recall having changed the priority once but I don't remember why. In any case, it might be helpful to someone else.
Upvotes: 2
Reputation: 128013
You don't need to remove and add the Rectangle on each timer tick, or reset its properties each time.
Just increment the value of the Canvas.Left property:
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);
}
}
The movement would however be much smoother with an animation:
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);
}
Upvotes: 2