Question

I'm trying to make a minesweeper clone and i'm having trouble with the mouse events. If i press a mousebutton on a picturebox and then move the mouse to another box, the mouseup event will still have the same object sender even though it happens on another control.

I need the mousedown event so that i can see if both mouse buttons have been pressed, unfortunately the mouseup event doesn't seem to care where the cursor is when i release the button.

If i'm not expressing myself clearly, think minesweeper. I want to be able to leftclick, rightclick, click both together and also be able to move the cursor after pressing down and open the tile where i release it.

Does anyone have any ideas?

Was it helpful?

Solution

I managed to figure something out that will do the trick, gonna leave it here if someone else needs it in the future.

private void MouseUp(object sender, MouseEventArgs e)
    {
        Point ptCursor = Cursor.Position;
        ptCursor = PointToClient(ptCursor);
        PictureBox pBox = (PictureBox)GetChildAtPoint(ptCursor);
        pBox.BackColor = System.Drawing.Color.Blue;
    } 

I set up a simple form with some pictureboxes and when the mouseup-event happens it checks for the control under the cursors position and you can then use that for your needs. The problem i was having was that the mouseup event was tied to the control where the mousedown-event happened, and thus i couldn't access the control the cursor was in when the mouseup-event happened.

I have only been programming for about 4 weeks so this solution might be very flawed so if there are any problems with it some feedback would be great.

OTHER TIPS

Personally, I do this by having a form level Point variable that I update on every MouseMove event. Then, when the other mouse events happen, they have the latest available.

I would do like this:

  1. Create subclassed buttons to contain game assets as theire picture.
  2. Create a custom control and add as many as buttons necessary
  3. On mouse click I would check agains Contains method of the Bounds to see if the click occured on that specific button, or another way handle the button click inside the custom controll

It would help more if we see some of your code and propably a screenshot.

Update:

This is an example of how to handle clicks, using delegates.

public partial class MineSweeper : UserControl
{
    public MineSweeper()
    {
        InitializeComponent();
    }

    private void MineSweeper_Load(object sender, EventArgs e)
    {
        this.BackColor = Color.Red;
        for (int i = 0; i < 16; i++)
        {
            var button = new Button();
            button.Name = "Button" + i;
            button.Size = new Size(50, 50);
            button.ForeColor = Color.Yellow;

            button.ForeColor = Color.Black;
            button.Click += delegate
            {
                MessageBox.Show("You have clicked me! I am " + button.Name);
            };
            flowLayoutPanel1.Controls.Add(button);
            flowLayoutPanel1.Invalidate();
        }

        this.Invalidate();
    }
}

Just add a new UserControl from the designer, add a flowLayoutPanel to it and set its dock property to full.

[VS 2017 c#] Using MouseEventArgs for mouse position at mouse down/up works only when the point is captured inside left mouse button as shown below.

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
   //??? this changes at UP time and becomes same as MouseArgsUpPoint 
   //MouseArgsDownPoint = new Point(e.X, e.Y);
   //same as above, MouseArgsDownPoint = PointToClient(MousePosition);

   if (e.Button == MouseButtons.Left)
   {
       //inside here it works fine and Up/Down points are different and correct
       MouseArgsDownPoint = new Point(e.X, e.Y);
   }
}


private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    MouseArgsUpPoint = new Point(e.X, e.Y);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top