How to interrupt mouseUp event if control has changed
I just finished playing "Minesweeper" in Windows-Forms that I made for practice.
Everything works fine, but I found that if you press and hold a button, it will expand even if the mouse no longer points to that button.
Do you have a simple idea how I can fix this?
Code:
/// <summary>
/// Build up a new Gamefield with the number of buttons, the user has selected
/// </summary>
private void DrawGameField()
{
_buttons = new Button[_xLength, _yLength];
for (int yPos = 0; yPos < _yLength; yPos++)
{
for (int xPos = 0; xPos < _xLength; xPos++)
{
var btn = new Button()
{
Tag = new Point(xPos, yPos),
Location = new Point(xPos * 30, yPos * 30),
Size = new Size(30, 30),
};
_buttons[xPos, yPos] = (Button)btn;
btn.MouseUp += btn_Click;
_gamePanel.Controls.Add(btn);
}
}
}
/// <summary>
/// Is called when a field is left-clicked
/// </summary>
private void LeftMouseClick(object sender, MouseEventArgs e)
{
var btn = sender as Button;
Point pt = (Point)btn.Tag;
// If there already a flag on the field make it unclickable for left mouseclick
if (btn.Image != null)
return;
_game.UnfoldAutomatically(pt.X, pt.Y);
btn.Text = (_game.ReturnNumberInField(pt.X, pt.Y)).ToString();
// If clicked field was not a bombfield
if (btn.Text != "-1")
UnfoldFields();
else
LooseGame();
}
Each button receives a mouseUp event in the DrawGameField method. Each button also receives a tag in this method, so it can be identified. LeftMouseClick are calls as soon as the user (mouseUp) -clickes on one of the buttons of the playing field.
I want to undo this if the button on which the left mouse button was displayed is different from the button on which the button was pressed.
This should give the user a chance to change their mind ... he can actually click on the field and then realizes that he doesn't want to expand that field, but in my solution, he can't undo his click yet ...
source to share
Well guys, with a little help, I have the correct solution to the problem that looks like this:
Use "MouseClick", not "MouseUp" or "MouseDown".
Why?
MouseClick internally uses MouseDown, then executes MouseCapture (notifications that were controlled under the mouse pointer and checks if the mouse was pointing at this control) if true -> click event if false -> return
Working code:
/// <summary>
/// Build up a new Gamefield with the number of buttons, the user has selected
/// </summary>
private void DrawGameField()
{
// _xLength is the length of the field in x-direction
// _yLength is the length of the field in y-direction
var buttons = new Button[_xLength, _yLength];
// Filling the buttonArray
for (int yPos = 0; yPos < _yLength; yPos++)
{
for (int xPos = 0; xPos < _xLength; xPos++)
{
var btn = new Button()
{
Tag = new Point(xPos, yPos),
Location = new Point(xPos * 30, yPos * 30),
Size = new Size(30, 30)
};
// Apply a clickEvent to every button
btn.MouseClick += Button_MouseClick; //first change here: Use MouseClick!!!
buttons[xPos, yPos] = btn;
}
}
AddGameButtonsToPanel(buttons);
}
/// <summary>
/// Adds Buttons to the gamepanel
/// </summary>
private void AddGameButtonsToPanel(Button[,] buttons)
{
_buttons = buttons;
_gamePanel.SuspendLayout();
try
{
foreach (var btn in buttons)
_gamePanel.Controls.Add(btn);
}
finally
{
_gamePanel.ResumeLayout();
}
}
/// <summary>
/// Checks which mouse-button was clicked and calls the correct method for that button
/// </summary>
private void Button_MouseClick(object sender, MouseEventArgs e)
{
// If it is the firs time a button is clicked, the stopwatch is started
if (_firstClick)
StartStopWatch();
var btn = sender as Button;
Point pt = (Point)btn.Tag;
if (e.Button == MouseButtons.Left)
Button_LeftClick(btn, pt);
else
Button_RightClick(btn, pt);
}
source to share