views:

85

answers:

6

Not sure what is the best way to word this, but I am wondering if a dynamic variable name access can be done in C# (3.5).

Here is the code I am currently looking to "smarten up" or make more elegant with a loop.

    private void frmFilter_Load(object sender, EventArgs e)
    {
        chkCategory1.Text = categories[0];
        chkCategory2.Text = categories[1];
        chkCategory3.Text = categories[2];
        chkCategory4.Text = categories[3];
        chkCategory5.Text = categories[4];
        chkCategory6.Text = categories[5];
        chkCategory7.Text = categories[6];
        chkCategory8.Text = categories[7];
        chkCategory9.Text = categories[8];
        chkCategory10.Text = categories[9];
        chkCategory11.Text = categories[10];
        chkCategory12.Text = categories[11];  


    }

Is there a way to do something like ("chkCategory" + i.ToString()).Text?

A: 

You don't need dynamic for that. Put chkCategory1 - 12 in an array, and loop through it with a for loop. I would suggest you keep it around in a field and initialize it at form construction time, because chkCategory seems to be related. But if you want a simple example of how to do it in that simple method, then it would be something like this:

private void frmFilter_Load(object sender, EventArgs e)
{
    var chkCategories = new [] { chkCategory1, chkCategory2, chkCategory3, .......... };
    for(int i = 0 ; i < chkCategories.Length ; i++ ) 
        chkCategoies[i].Text = categories[i];
}

You know more about the application, so you could perhaps avoid writing out all the control names - for instance, if they are placed on a common parent control, then you could find them by going through it's children.

driis
I don't think the OP meant `dynamic` dynamic.
Henk Holterman
How does this work with the WinForms designer? Would I need to manually define all placement and properties in code?
Awaken
A: 

No, but you could do something like this (untested, beware of syntax errors):

private readonly CheckBox[] allMyCheckboxes = new CheckBox[] { chkCategory1, chkCategory2, ... }

Then you just need to do

for (i = 0; i < 12; i++) allMyCheckboxes[i].Text = categories[i];
Heinzi
+5  A: 

Yes, you can use

  Control c = this.Controls.Find("chkCategory" + i.ToString(), true).Single();
  (c as textBox).Text = ...;

Add some errorchecking and wrap it in a nice (extension) method.


Edit: It returns Control[] so either a [0] or a .Single() are needed at the end. Added.

Henk Holterman
Nice! I stand corrected from my comment as left on the question.
fauxtrot
@faux trot, this is a library feature, not language. It's not really the identifier we're searching on but the Name property. The 2 are kept in sync though.
Henk Holterman
Thanks. This is a technique I wasn't familiar with, but I have a couple situations where it will be nice.
Awaken
+1  A: 
for(...)
{
     CheckBox c = this.Controls["chkCategory" + i.ToString()] as CheckBox ;

     c.Text = categories[i];  
}
Rony
Perfect. Worked like a charm.
Awaken
+2  A: 

You can do that with reflection. But don't.

It's more proper to instantiate a list of contols, add them programmatically to your form, and index that.

jdv
+1  A: 

Sometimes it can help to put your controls into an array or collection as such:

Checkbox[] chkCataegories = new Checkbox[] { chkCategory1, chkCategory2 ... };
for(int i = 0; i < chkCategories.Length; i++)
    chkCategories[i].Text = categories[i];

As another approach, you can dynamically create your checkboxes at runtime instead of design time:

for(int i = 0; i < categories.Length; i++)
{
    Checkbox chkCategory = new chkCategory { Text = categories[i] };
    someContainer.Controls.Add(chkCategory);
}

At least with dynamically created controls, you don't need to modify your GUI or your form code whenever you add new categories.

Juliet
Is there a good way to do this using the WinForms designer in VS? Or would I have to drop the designer and build the form with code dynamically in the Load?
Awaken