I’ll try and keep this generic for future refference.
Let’s suppose our Form has a grid of Squares (RectangleShapes which we’ll reffer to individually as “points”.) Since the size of this grid can vary before the Form loads, we’ve create all the points in a panel when we first load our Form and can use…
foreach (Squares point in mySquares)
…when we want to change their behavior or appearance. Now, we’ve already developed code to change the color of each individual point when the user clicks left or right. It would look something like:
private void panelGrid_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
{
foreach (Squares point in mySquares)
{
if (point.Rectangle.Contains(e.Location)) // determine which point to use
{
if (e.Button == MouseButtons.Left)
{
Pencil(point); // left-click to fill color
}
else
{
Erase(point); // right-click to erase color
}
}
}
panelGrid.Invalidate(); // refreshes grid
}
}
And this works like a charm. But suppose we need to change this code: Now we also want the color to change when a mouse button is held down, and the cursor is moved onto a new point. (Sort of like MS-Paint: Dragging the pencil tool over multiple pixels fills each one in turn.)
What confuses me is the proper way to implement this behavior properly. To my understanding, I would want the Pencil/Eraser methods to call when:
A.) The mouse enters a “point” AND a button is already held down.
OR
B.) A mouse button becomes pressed. (See above code)
Where this gets tricky for me is determining how best to implement the new checks, and how to perform them on the individual points in the grid – or even if that’s necessary. Any tips?
Sounds like you want the MouseDown and MouseMove events to do the same thing:
then try calling it from both events:
Look into using a double-buffered panel to make the control less flicky since invalidating the panel on a MouseMove event can be quite intensive: