7

How do I build an array of buttons in a Winforms application?

What I am trying to do is this: I have a lot of buttons in a sort of calendar arrangement, that are indicating time slots. IE: Monday0700Button, Monday0730Button, Monday0800Button, and so on in 30min intervals.

I have a xml database, where one of the fields for appointments is <Duration> When the duration = 0.5hrs, and the <Time> field equals "07:00am", to color the 'Monday0700Button'. When the Duration is 1.0hrs, I want it to populate 'Monday0700Button' as well as the following time slot button of 'Monday0730Button'.

Any ideas? Thanks.

2
  • 3
    Not entirely related to the question but just looking ahead a little bit , you might want to have a look at devexpress.com/Products/NET/Controls/WinForms/Scheduler , to use as a calendar planner instead of writing your own , you will get alot more out of it for less effort Commented Nov 5, 2009 at 4:04
  • +1 stalkerh: We use that control (well the whole enterprise suite) where I work with some great results. Couldn't recommend it enough. Commented Nov 5, 2009 at 5:12

5 Answers 5

7

Yes, you can build a list of buttons like below.

List<Button> listOfButtons = new List<Button>();
listOfButtons.Add(yourButton);
Sign up to request clarification or add additional context in comments.

2 Comments

I think your answer might be incomplete. A list of button objects is useless unless the buttons can be displayed and used on a form. How does one hook up events to each button?
@Robert Harvey: in this example, you would have to add the event handlers programatically.
3

Yes, it's no problem to build an array of Buttons, or any object. You won't be able to see them in the Visual studio designer, but they'll work just fine.

A long time ago I used a 2-D array of buttons to build the UI for an calculator app. I had used an HP-15C for a long time, and missed it.

alt text

The array approach worked fine.

  Button[] numberButtons=new Button[] { btn0, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9, btnDecimalPt};
  Button[] operationButtons=new Button[] { btnDiv, btnMult, btnSubtract, btnAdd };

  foreach (var b in numberButtons)
       b.Click += new System.EventHandler(this.Number_Click);

  foreach (var b in operationButtons)
      b.Click += new System.EventHandler(this.Operation_Click);

  // etc

  Button[][] allButtons=
  {
      new Button[] {btnSqrt, btnExp, btn10x, btnPow,btnMultInverse, btnCHS, null, null, null, null}, 
      new Button[] {btnN, btnInterest, btnPMT, btnPV, btnFV, null, btn7, btn8, btn9, btnDiv}, 
      new Button[] {btnLn, btnLog, btnSine, btnCosine, btnTangent, btnPi, btn4, btn5, btn6, btnMult}, 
      new Button[] {btnRoll, btnSwap, btnCLRfin, btnCLX, btnCLR, btnEnter, btn1, btn2, btn3, btnSubtract}, 
      new Button[] {btnInt, btnFrac, btnFix, btnStore, btnRecall, null, btn0, btnDecimalPt, btnNotUsed, btnAdd}
  };

  // programmatically set the location
  int col,row;
  for(row=0; row < allButtons.Length; row++)
  {
      Button[] ButtonCol= allButtons[row];
      for (col=0; col < ButtonCol.Length; col++)
      {
          if (ButtonCol[col]!=null)
          {
              ButtonCol[col].TabIndex = col + (row * allButtons.Length) +1;
              ButtonCol[col].Font = font1; 
              ButtonCol[col].BackColor = System.Drawing.SystemColors.ControlDark;
              ButtonCol[col].Size=new System.Drawing.Size(stdButtonWidth, stdButtonHeight);
              ButtonCol[col].Location=new Point(startX + (col * stdButtonWidth), 
                                                startY + (row * stdButtonHeight) ) ;
          }
      }
  }

1 Comment

When I do this, I get a runtime error as soon as it hits foreach (var b in numberButtons) b.Click += new System.EventHandler(this.Number_Click);
3

Yep, definitely possible, but probably unnecessary.

If I understand you correctly, you should be able to add a FlowLayoutPanel to your Form and then loop through your XML, instantiating a new Button, as necessary. Wire up the event handler for the Click event, then add the button to the FlowLayoutPanel by calling the Add() method off of the Controls property on your FlowLayoutPanel.

while (reader.Reader())
{
    // Parse XML here

    // Instantiate a new button that will be added to your FlowLayoutPanel
    Button btn = new Button();

    // Set button properties, as necessary
    btn.Text = "Foo";
    btn.Click += new EventHandler(SomeButton_Click);

    // Add the button to the FlowLayoutPanel
    flowLayoutPanel.Controls.Add(btn);
}

While a FlowLayoutPanel makes it easy to do the layout for your buttons, it might not work for you. If that's the case, you will have to work out the X and Y coordinates for your buttons as you loop through the XML.

One problem that you will encounter with the above approach is that it always calls the exact same event handler. As a result, you will have to come up with a way to determine which button has been clicked. One approach might be to extend the Button control to provide additional properties that can be used to acknowledge the time period.

Comments

0

Buttons, like all GUI elements, are objects just like any other (that also happen to be displayable). So yes, you can have arrays, lists, dictionaries - whatever you want containing buttons. Taylor L's response has some sample code.

Comments

0

Yes, this is possible, as Taylor L demonstrated. The only catch is that VB6-style control arrays, created by copying and pasting the control, can no longer be done in the forms editor.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.