views:

712

answers:

6

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.

+1  A: 

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

List<Button> listOfButtons = new List<Button>();
listOfButtons.Add(yourButton);
Taylor Leese
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
@Robert Harvey: in this example, you would have to add the event handlers programatically.
FrustratedWithFormsDesigner
You'll have to do better than that to get my upvote.
Robert Harvey
A: 

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) ) ;
          }
      }
  }
Cheeso
A: 

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.

Smashery
A: 

yes you can, what technology? winforms? asp? wpf?

with winforms many controls gets really ineffiecient and slow

Keith Nicholas
A: 

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.

FrustratedWithFormsDesigner
A: 

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.

senfo