5

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?

4
  • I may be completely showing my ignorance of the dynamic portion of the new C# features, but I thought that C# was a compiled language. Therefore to accomplish this you would have to create an instance of the compiler, generate the code and then execute the code within the context of the thread owning the controls. Its not practical. Commented Aug 11, 2010 at 14:21
  • General Question in Response to Answers: When using the WinForms designer, what is the best method for handling the array of checkboxes? Commented Aug 11, 2010 at 14:30
  • That what reflection was invented for (In your special case you can also access the control by their names). Commented Aug 11, 2010 at 14:35
  • @ Awaken: You can use the System.Windows.Forms.CheckedListBox control, as I have in my answer. Just drag the control onto your designer. If you already know the items, set them up with the Items property. Otherwise, you can set the DataSource property, perhaps in the form's constructor after the call to InitializeComponents() Commented Aug 11, 2010 at 14:50

7 Answers 7

7

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Nice! I stand corrected from my comment as left on the question.
@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.
Thanks. This is a technique I wasn't familiar with, but I have a couple situations where it will be nice.
5
for(...)
{
     CheckBox c = this.Controls["chkCategory" + i.ToString()] as CheckBox ;

     c.Text = categories[i];  
}

1 Comment

Perfect. Worked like a charm.
2

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.

Comments

1

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.

1 Comment

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?
0

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.

2 Comments

I don't think the OP meant dynamic dynamic.
How does this work with the WinForms designer? Would I need to manually define all placement and properties in code?
0

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];

Comments

0

The "this.Controls["chkCategory" + i.ToString()]" and "this.Controls.Find("chkCategory" + i.ToString(), true)" both do not work... the former informs you that the contents of the [] are not an int and the latter that ControlCollection does not contain a definition for Find.

Use "Control myControl1 = FindControl("TextBox2");" instead.

I needed this form as I was looping through another array, extracting values and using them to populate form fields. Much easier to look for label1, label2, label3, etc.

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.