Making an indexed control array?
Asked Answered
D

7

7

Has C# indexed control arrays or not? I would like to put a "button array" for example with 5 buttons which use just one event handler which handles the index of all this 5 controls (like VB6 does). Else I have to write for each of these 5 buttons one extra event handler. And if I have 100 buttons, I need 100 event handlers? I mean something like that:

TextBox1[i].Text="Example";

It could make coding definitely easier for me to work with control arrays. Now I have seen, that C# at least has no visible array functionality on user controls and no "index" property on the user controls. So I guess C# has no control arrays, or I must each element call by known name.

Instead of giving 100 TextBoxes in a for loop 100 incrementing values, I have to write:

TextBox1.Text = Value1;
TextBox2.Text = Value2;
...
...
TextBox100.Text = Value100;

A lot of more work + all these 100 event handlers each for one additional TextBox extra.

Ddt answered 23/7, 2012 at 21:41 Comment(6)
Every parent control has a property .Controls which gives access to a collection of child controls. If you place all of your textboxes/buttons inside the same parent container, you can reference them through the child controls list.Tress
You can assign the same event handler to multiple controls, you do not need to create a new event handler implementation for each control instance.Accra
You may have some luck implementing ICollection<T> where T : Control, but you cannot add an event handler to an array.Gitagitel
Couldn't you put all the controls into an array using reflection (once) and then use it as an array thereafter? Of course - if you're only after the event handlers there are other ways as suggested.Profession
The burden of a user exposed to a UI disaster with a hundred text boxes, repeatedly, needs to be properly matched with the purgatory a programmer deserves for creating one. Its only fair.Feasible
Could you tell more - why all your controls need same event handler?Barter
C
3

As I mentioned in comment to a solution by HatSoft, C# Winforms does not allow you to create control arrays like old VB6 allowed us. The nearest I think we can get to is what HatSoft and Bert Evans in their posts have shown.

One thing that I hope would satisfy your requirement is the event handler, you get a common event handler and in the event handler when you typecast the "sender" you get the control directly just like you would in VB6

C#

TextBox textBox = sender as TextBox;

VB6

TextBox textBox = TextBox1[i];

So the only trouble you might have is wiring those 100 TextBoxes to a single event handler, if you are not creating the controls dynamically through code rather creating it manually at design time then all one can suggest is group them in a container like say Panel. Then on Form Load wire them all up to a single event handler like this:

foreach (Control control in myTextBoxPanel.Controls)
{
    if(control is TextBox)
         control.TextChanged += new EventHandler(control_TextChanged);
}
Classieclassification answered 24/7, 2012 at 4:10 Comment(0)
M
10

I know I'm a little late to this party, but this solution will work:

Make a global array:

    TextBox[] myTextBox;

Then in your object's constructor, after the call to

    InitializeComponent();

initialize your array:

    myTextBox = new TextBox[] {TextBox1, TextBox2, ... };

Now you can iterate your array of controls:

    for(int i = 0; i < myTextBox.Length; i++)
        myTextBox[i].Text = "OMG IT WORKS!!!";

I hope this helps!

Pete

Macao answered 10/5, 2015 at 13:34 Comment(0)
C
3

As I mentioned in comment to a solution by HatSoft, C# Winforms does not allow you to create control arrays like old VB6 allowed us. The nearest I think we can get to is what HatSoft and Bert Evans in their posts have shown.

One thing that I hope would satisfy your requirement is the event handler, you get a common event handler and in the event handler when you typecast the "sender" you get the control directly just like you would in VB6

C#

TextBox textBox = sender as TextBox;

VB6

TextBox textBox = TextBox1[i];

So the only trouble you might have is wiring those 100 TextBoxes to a single event handler, if you are not creating the controls dynamically through code rather creating it manually at design time then all one can suggest is group them in a container like say Panel. Then on Form Load wire them all up to a single event handler like this:

foreach (Control control in myTextBoxPanel.Controls)
{
    if(control is TextBox)
         control.TextChanged += new EventHandler(control_TextChanged);
}
Classieclassification answered 24/7, 2012 at 4:10 Comment(0)
C
2

Just create one handler and point all the buttons to it.

var ButtonHandler = (sender, args) => {
    var clicked = (Button)sender;
    if (clicked.Text == "whatever")
       //do stuff
    else
       //do other stuff 
};

button1.Click += ButtonHandler;
button2.Click += ButtonHandler;

Alternatively, if you are creating controls in code, you could use one of the techniques specified in this answer.

Caning answered 23/7, 2012 at 21:44 Comment(3)
Ah, you mentioned usercontrols and I leapt to a conclusion.Caning
Bottom line, create a single event handler, and assign it to the controls event.Caning
@Ddt The handler receives the sender as an argument. If you assign a value to each control, you can examine that value to determine which control was clicked.Caning
P
2

Instead of giving 100 TextBoxes in a for loop 100 incrementing values, I have to write:

for(int i = 0; i <100; i++)
{
   TextBox t = new TextBox(){ Id = "txt_" + i, Value = "txt_" + i};
   t.TextChanged += new System.EventHandler(this.textBox_Textchanged);
  Page.Controls.Add(t);

}

//and for event on TextChanged
private void textBox_Textchanged(object sender, EventArgs e)
    {
        TextBox textBox = sender as TextBox;

        if (textBox != null)
        {
////
        }
    }
Plastometer answered 23/7, 2012 at 21:48 Comment(1)
@feedwall: No you can not have an array like you can in VB6 at design time. However, you could have a common event handler for all the controls, but you will need to manually wire them up either at design time or through code.Classieclassification
S
1

Another thing to note: if you really need to edit 100 strings on one form, you should probably think about whether 100 text boxes is really the best way to do it. Perhaps a ListView, DataGridView, or PropertyGrid would be better suited.

This applies almost any time you think you need a huge array of controls.

Saporous answered 7/10, 2013 at 19:3 Comment(0)
D
0

If you are working with Web Forms and not MVC, you can acces a collection of controls on the page as shown in Using the Controls Collection in an ASP.NET Web Page. Essentially the controls collection is a tree with the page hosting the first level of child controls and some items having children of their own. See How to: Locate the Web Forms Controls on a Page by Walking the Controls Collection for an example of how to follow the tree.

Also, see How to: Add Controls to an ASP.NET Web Page Programmatically.

You can use the same event handler for multiple items as long as the signature required is the same.

For Windows Forms this is nearly identical since they're based on similar architectural models, but you'll want Control.Controls Property and How to: Add Controls to Windows Forms.

Domitian answered 23/7, 2012 at 21:48 Comment(1)
The Windows Forms and Web Forms models are nearly identical as far as basic architecture goes. Much of the technique applies. I've added a little more to the answer.Domitian
P
0

Keeping it simple:

TextBox[] keybox = new TextBox[16];   //create an array

for (int i=0; i<16; i++) 
{
    keybox[i] = new TextBox();        //initialize (create storage for elements)
    keybox[i].Tag = i;                //Tag prop = index (not available at design time)
    keybox[i].KeyDown += keybox_down; //define event handler for array
}

private void keybox_down(object sender, KeyEventArgs e)
{
    int index = (int)((TextBox)sender).Tag    //get index of element that fired event
    ...
}
Primarily answered 7/8, 2018 at 22:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.