1

I'm making a chess game in C#, and I'm using 64 pictureBoxs to display the board. Now, I'm trying to figure out how to determine where the user clicks to allow the user to move pieces by clicking different tiles/pictureBoxes. I'm new to C#, but I'm trying to do it by detecting where the mouse is whenever it's clicked. I've been using:

void MainFormClick(object sender, EventArgs e){
            Point mousePosition = pictureBox1.PointToClient(Cursor.Position); //pictureBox1 is in upper-left
            int indexClicked = (mousePosition.X / tileSize) + (8 * (mousePosition.Y / tileSize));
            if (indexClicked >= 0 && indexClicked <= 63){
                //do code things?
            }
            this.Text = "Chess - " + indexClicked;
        }

I assume this isn't working because the user isn't actually clicking on the form, but on the pictureBoxes. I'd rather not make 64 pictureBox*Click methods, so is there some other way I should be doing this or method I should be using?

EDIT: I just looked at How to get control under mouse cursor. My code needs to be changed a little to better determine which pictureBox the mouse is over when it's clicked, but my real problem is that it doesn't appear that clicking on the pictureBoxes runs the above method. I'm looking for a way to run a block of code whenever the mouse is clicked, regardless of what control or part of the form it's clicked on.

KnightOfNi
  • 770
  • 2
  • 10
  • 17
  • 1
    possible duplicate of [How to get control under mouse cursor?](http://stackoverflow.com/questions/2411062/how-to-get-control-under-mouse-cursor) – Hamid Pourjam Aug 16 '15 at 18:08
  • 2
    you can write __one__ Click event and wire all 64 PBs to the __same__ event. In it you can use the `sender` parameter to decide which one was clicked.. - And you could add them dynamically, making it even simpler to code and maintain. – TaW Aug 16 '15 at 18:08
  • @dotctor I don't think so. I tried to make what I was looking for a bit more clear in my edit. This person was trying to figure out where their mouse was, I'm just trying to figure out when it's clicked, no matter what it's clicked on. – KnightOfNi Aug 16 '15 at 18:30
  • @TaW Ah, that pretty much solved my problem. I'm wiring them all to the same event, then pasting the code in my question right in... If you'd like to post as an answer, I'll definitely at least give it an upvote :). It really would be nice if there was a way to run some code no matter where the mouse is clicked, though... – KnightOfNi Aug 16 '15 at 18:33
  • Then you can accept Paul's answer, who wrote out what I suggested in a few more words.. I would add all 64 to a large one called Board and caluculate their sizes and positions.. (((Well actually I would probably only use one and draw the images, but that's not for the faint of heart..))) – TaW Aug 16 '15 at 18:34
  • The normal mouse events only go to the controls they hit; you may want to look up a global mouse hook and you can at any time check the `Control.MousePosition` – TaW Aug 16 '15 at 18:40
  • In addition to wiring up the PBs to the same Click() handler, I'd place them inside a TableLayoutPanel (arranged in a grid) so that you can use the [TableLayoutPanel.GetPositionFromControl](https://msdn.microsoft.com/en-us/library/system.windows.forms.tablelayoutpanel.getpositionfromcontrol(v=vs.100).aspx) method and easily determine which row/column the user clicked on. – Idle_Mind Aug 16 '15 at 18:48

3 Answers3

2

I would probably just use the normal Click event. Pictureboxes have a Click event that you can bind to. I'm not sure how you're adding them, but for 64 of them I'd probably add them dynamically in a loop. As you create each one, bind the Click event to a common handler. Name each control in a way that makes it easy to figure out where it is located. Then in the handler you get an object reference to the picturebox that was clicked and can figure out what to do from there.

Paul Mrozowski
  • 6,604
  • 9
  • 34
  • 47
  • Thanks, this is almost certainly what I'll end up using! I do think it's strange that I can't just get a method to run on every click, though... – KnightOfNi Aug 16 '15 at 18:39
  • Well, you can but you need to hook it up to the click events – TaW Aug 16 '15 at 18:41
1

What you can do is :

  1. Create 64 pictureBoxes and name them something like squareA1, squareF4 and so on

  2. Create Click event handler

  3. Attach this event handler to all of your pictureboxes in designer

  4. Use object sender to find out in what picturebox event was invoked

The code might look like:

    private void square_Click(object sender, EventArgs e)
    {
        PictureBox target = sender as PictureBox;
        MessageBox.Show(target.Name); // displays pictureBox name
    }

Code that is added automatically by designer to each picturebox :

this.squareA2.Click += new System.EventHandler(this.square_Click);

Alternatively you can create all 64 pictureboxes in a loop, calculate their positions, and attach this event handler to each of them...

Fabjan
  • 13,506
  • 4
  • 25
  • 52
  • This is pretty much what I ended up doing. Because of the way I'm representing my board, I just copied and pasted the `MainFormClick` method from my question into the `square_Click` handler and was thus able to get the index of the tile in the array I'm using to represent it. – KnightOfNi Aug 16 '15 at 20:43
0

You are already calculating where the mouse cursor is, so you should really just change to use 1 large picture box for the entire board and wire the click event to your posted method.

Dietz
  • 578
  • 5
  • 14