0

i'm newbie here and also in c#.

my project is to create a box in grid view. then when click desired box, i'll get the box coordinate or position and box will change the colour. when click another box, the previous box colour will change to original.

the box will resize when total size for rows x cols more than panel2 size.

i wanna extend the function of code by add new button NEXT, when click, then next picture box will be highlight and also coordinate will update. how to relate new button with existing picture box?

        for (int cols = 0; cols < COLUMNS; cols++)
        {
            for (int rows = 0; rows < ROWS; rows++)
            {                    
                PictureBox newPic = new PictureBox();
                newPic.Height = HEIGHT;
                newPic.Width = WIDTH;
                newPic.BackColor = Color.Maroon;

                int x = cols * (HEIGHT + SPACE);
                int y = rows * (WIDTH + SPACE);
                newPic.Location = new Point(x + SPACE, y + SPACE);

                newPic.Click += NewPic_Click;

                items.Add(newPic);
                this.panel2.Controls.Add(newPic);

            }
        }

enter image description here

  • There are different options, the easiest based on your code... when you create each `PictureBox` set the name (e.g. pic_1, pic_2, etc.), then in your `NewPic_Click` Event Handler, look at the sender object's name and then use that name to get the item from your `items` list or `panel` control. Once you have the picture box you can apply your changes. Also, since sender is an object type you will need to cast it to a `PictureBox` before you can work with it as a `PictureBox`. – quaabaam Jan 28 '23 at 01:33
  • Use TableLayoutPanel: [Example](https://stackoverflow.com/a/33969228/3110834), [another example](https://stackoverflow.com/a/34426939/3110834), [documentations](https://learn.microsoft.com/en-us/dotnet/desktop/winforms/controls/walkthrough-arranging-controls-on-windows-forms-using-a-tablelayoutpanel?view=netframeworkdesktop-4.8&WT.mc_id=DT-MVP-5003235). – Reza Aghaei Jan 28 '23 at 02:17

1 Answers1

0

Just for color switching, you only need the PictureBox which has been clicked on. It is stored in the sender parameter.

I you want the coordinates, you need to store some information on the PictureBox. You don't want to specify 50 handlers. The way I would do is; to make use of the Tag property of a Control.

Your for-loop would be something like:

for (int cols = 0; cols < COLUMNS; cols++)
{
    for (int rows = 0; rows < ROWS; rows++)
    {                    
        PictureBox newPic = new PictureBox();
        newPic.Height = HEIGHT;
        newPic.Width = WIDTH;
        newPic.BackColor = Color.Maroon;

        // instead of the coordinates, store the indices (for col, row)
        newPic.Tag = new Point(cols, rows);

        // I would use the Width on the cols, instead of the Height.
        int x = cols * (WIDTH + SPACE); 
        int y = rows * (HEIGHT + SPACE);
        newPic.Location = new Point(x + SPACE, y + SPACE);
        newPic.Click += NewPic_Click;

        items.Add(newPic);
        this.panel2.Controls.Add(newPic);

    }
}

And your handler would be something like:

// a field to store the previous selected picturebox.
private PictureBox _currentPictureBox = null;

private void NewPic_Click(object sender, EventArgs e)
{
    // the picturebox which has been clicked, is stored in the sender object, but you need to cast it to a PictureBox.
    PictureBox pb = (PictureBox)sender;

    // just for the extra use of the Tag.
    var location = (Point)pb.Tag;
    // location.X Contains the Column index
    // location.Y Contains the Row index



    // did we have a previous picturebox?
    if(_currentPictureBox != null)
    {
        // change the previous pictureBox back to Maroon
        _currentPictureBox.BackColor = Color.Maroon;
    }

    // change the current to blue
    pb.BackColor = Color.Blue;

    // store the new one as the current. (so we can revert it)
    _currentPictureBox = pb;
}

I haven't tested it, only in a notepad. So there might be some typo's. But I hope you get the idea.

Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
  • hi and thanks for the given answer. it work perfectly. i wanna extend the function above code by add new button NEXT, when click, then next picture box will be highlight and also coordinate will update. how to relate new button with existing picture box? – mastermind 007 Jan 30 '23 at 03:39
  • Instead of searching for PictureBox controls on you form, you could add all PictureBoxes to a list and keep an extra variable for the `currentIndex`. On the next button: increase the index, check it's bounds (you don't want to read outside the list. – Jeroen van Langen Jan 30 '23 at 07:08
  • all PictureBoxes already in the list (items.Add(newPic);) but i didn't found a way to get picturebox get selected by Next button and change to another picturebox when click again. – mastermind 007 Jan 31 '23 at 06:10
  • Got a compilable version in github? – Jeroen van Langen Jan 31 '23 at 07:19
  • sorry. never use github. tried find out about it yesterday. should i upload the whole project file to github? – mastermind 007 Feb 01 '23 at 02:07