1

I Want the program get a pic of user ,then convert image to puzzle (for example 100 piece) then make 100 picture box.

I using this following code for 4 and 9 piece.

if (Image_Num.SelectedIndex == 0)
        {
            PB = new PictureBox[4];

            int W, H;
            var imgarray = new Image[4];
            var img = User_Image.Image;
            W = img.Width / 2;
            H = img.Height / 2;
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    var index = i * 2 + j;
                    imgarray[index] = new Bitmap(W, H);
                    var graphics = Graphics.FromImage(imgarray[index]);
                    graphics.DrawImage(img, new Rectangle(0, 0, W, H), new Rectangle(i * W, j * H, W, H), GraphicsUnit.Pixel);
                    graphics.Dispose();
                }
            }

            PB[0] = new PictureBox
            {
                Name = "P1",
                Size = new Size(100, 100),
                Location = new Point(394, 60),
                Image = imgarray[0],
                SizeMode = PictureBoxSizeMode.StretchImage
            };
            ...

            PB[0].MouseEnter += Images_M_E;
            ...


            PB[0].MouseLeave += Images_M_L;
            ...


            PB[0].MouseClick += Images_C;
            ...

            Controls.Add(PB[0]);
            ...
        }

I can't do this for 100 times or more.

Thanks.

braX
  • 11,506
  • 5
  • 20
  • 33
  • You need to learn to use variables in a more useful way. To set up a 10x10 puzzle you have a variable xyparts= 10; if you want a non-square puzzle have xParts and yParts! - Now for whole work happens in the double loop. Don't call the loop counter i and j! Call them x and y or col and row! Always make text readable! - Use the variable to calculate the loop limits and of course the Locations!! Avoid 'magic' numbers in your code! – TaW Sep 02 '18 at 16:51
  • You can create the Pboxes right in the loop, create and assign the images and also hook up the code for your events. All pboxes should use the very same event! In these start by casting `sender` to `picturebox`! Do ask for more hints when you have tried to implement the changes. – TaW Sep 02 '18 at 16:53
  • There are too many problems here: you should be drawing in your Paint event handler; you should not be creating separate `PictureBox` controls for every piece of your puzzle. You need to get a book or tutorial and learn how to draw graphics. – Dour High Arch Sep 02 '18 at 17:17
  • @Dour: Good advice; but he is really young and we can't hope for him to get all things right from the start. First things first and here this is 'loops' ;-) – TaW Sep 02 '18 at 17:20

1 Answers1

2

Here is an example: The code taken from your question with minimal changes to make it flexible; I have implemented the above comments but not gone beyond that.

I hope you'll have fun studying it :-)

private void SetUpPuzzle_Click(int parts)  // use the number of parts on each side
{
    Control board = panel1;  // use the control you want to use or the form!
    int total = parts * parts;
    var PB = new PictureBox[total];

    var imgarray = new Image[total];
    var img = User_Image.Image;
    int W = img.Width / parts;
    int H = img.Height / parts;
    int size = 100;
    for (int x = 0; x < parts; x++)
    {
        for (int y = 0; y < parts; y++)
        {
            var index = x * parts + y;
            imgarray[index] = new Bitmap(W, H);
            using (Graphics graphics = Graphics.FromImage(imgarray[index]))
                graphics.DrawImage(img, new Rectangle(0, 0, W, H), 
                                   new Rectangle(x * W, y * H, W, H), GraphicsUnit.Pixel);
            PB[index] = new PictureBox
            {
                Name = "P"+ index,
                Size = new Size(size, size),
                Location = new Point(x * size, y * size),
                Image = imgarray[index],
                SizeMode = PictureBoxSizeMode.StretchImage
            };
            PB[index].MouseEnter += Images_M_E;
            PB[index].MouseLeave += Images_M_L;
            board.Controls.Add(PB[index]);
        }
    }
}

You can pass in any (reasonably small) number. You may also want to pass in the full image and you may want to make the size flexible; the 100x100 is the last magic number in the code. But all in your owm time..

Here are two examples for common events that all pboxes can use:

private void Images_M_E(object sender, EventArgs e)
{
    PictureBox pb = sender as PictureBox;  // here we get a reference to the actual pbox
    pb.BorderStyle = BorderStyle.FixedSingle;   // do what you..
}
private void Images_M_L(object sender, EventArgs e)
{
    PictureBox pb = sender as PictureBox;
    pb.BorderStyle = BorderStyle.None;   // ..want to do here
}

I left the code pretty much as it was; this means that not all issues are resolved. There is no obvious need for the arrays, really. The created images and pboxes are both added where they belong; no need to hold extra references in the arrays, which will go out of scope anyway after the code has run through.

Also your spelling of variables is a bit confused. All private filed should be camelCase, so you do not capitalize the first letter! Properties and Classes are PascalCase. Basically nothing should consist of consecutive caps (as I saw in your previous posts.)

TaW
  • 53,122
  • 8
  • 69
  • 111