4
\$\begingroup\$

I've written a Minesweeper program, but my code for generating the buttons is taking much longer than I'd like. Here is the GUI code:

        this.boardPanel.Controls.Clear();
        this.boardValues = new int[mode.size.Width, mode.size.Height];
        this.boardFound = new bool[mode.size.Width, mode.size.Height];
        this.boardButtons = new Button[mode.size.Width, mode.size.Height];
        EventHandler click = new EventHandler(btn_Click);
        for (int x = 0; x < boardButtons.GetLength(0); x++)
        {
            for (int y = 0; y < boardButtons.GetLength(1); y++)
            {
                boardButtons[x, y] = new Button();
                boardButtons[x, y].Size = new Size(Minesweeper.BUTTON_LENGTH, Minesweeper.BUTTON_LENGTH);
                boardButtons[x, y].Location = new Point(x * Minesweeper.BUTTON_LENGTH, y * Minesweeper.BUTTON_LENGTH);
                boardButtons[x, y].Tag = new Point(x, y);
                boardButtons[x, y].Click += click;
                this.boardPanel.Controls.Add(boardButtons[x, y]);
            }
        } 
        this.boardPanel.Size = new Size(mode.size.Width * Minesweeper.BUTTON_LENGTH, mode.size.Height * Minesweeper.BUTTON_LENGTH);
        this.Size = new Size(5 + this.boardPanel.Width + 5 + 8, this.tstMain.Height + 5 + this.boardPanel.Height + 5 + this.stsStatus.Height + 30);

As you can see I am creating an EventHandler for a method called btn_Click, outside of the loop, and assigning it to each button. This method reads the Tag field of the clicked button to determine which button as pressed.

In an Intermediate game with a board size of 16x16, generating the buttons takes approximately 2-3 seconds. I know WinForm controls aren't known for the best performance, but is there a way I can generate a number of buttons, assign Event handlers and add them to a panel more efficiently?

\$\endgroup\$
5
  • \$\begingroup\$ i think you need suspend and resume layout msdn.microsoft.com/en-us/library/… \$\endgroup\$
    – pm100
    Commented Jul 15, 2016 at 15:32
  • \$\begingroup\$ @pm100 I tried adding this.SuspendLayout() at the beginning of my code and this.ResumeLayout() at the end and saw no difference in the time it took to generate the buttons. I tried the same with this.boardPanel.SuspendLayout, ...etc. and got the same result. Thanks for your suggestion. \$\endgroup\$
    – Django
    Commented Jul 15, 2016 at 16:17
  • \$\begingroup\$ Using Control's isnt the only way to solve your real problem. Did you consider having only one big control and determine which "virtual" control was clicked from the mouse position? You could then just paint on the control directly.. \$\endgroup\$ Commented Jul 15, 2016 at 21:46
  • \$\begingroup\$ You're definitely doing something ridiculous if it's taking 2-3 seconds. You haven't posted enough code to replicate exactly what you're doing, but I did a quick test of creating buttons to form a 16 x 16 grid in a panel, with a width/height of 30 per button, in a loop similar to yours. Even without suspending layout, it took no more than 200ms. \$\endgroup\$
    – 404
    Commented Jul 16, 2016 at 11:56
  • \$\begingroup\$ Try to create all buttons fist and add them all at once to the panel with AddRange. \$\endgroup\$
    – t3chb0t
    Commented Jul 16, 2016 at 14:22

1 Answer 1

2
\$\begingroup\$
  • You don't really need the EventHandler you can just replace boardButtons[x, y].Click += click; withboardButtons[x, y].Click += btn_Click;. The += already works with delegates and kinda does that for you.

  • The only time you want to have this is when your method parameters have the same names as your class variables it appears that's not case for you, because I don't see any of the variables used without it.

Overall I really don't see what you can improve, you are simply assigning some values to some variables which really cant be speed up. Windows forms isn't really good for many controls at once that's it.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.