SyberWizard

I did this in my Visual dBASE days (yea, old code, old guy) but have not figured it out or found the "modern" solution. Should be pretty simple, I just need the magic words.

I have multiple objects that I want to change the properties of in mass. I was smart enough to use a number in the name, ie, foobar1, foobar2, ..., foobarn. I want to use a for or while loop to change them all, so I create a string,

string Changefoobar

build the string to include my counter n from within the loop,

Changefoobar = "foobar" + n + ".Enabled";

then make the change,

Changefoobar = true;

and let my loop run, changing all the object properties that I need changed. It makes for nice consise code, but my old brain isn't pulling this up from the depths! It is currently in "longhand" but that will quickly get out of control. The solution is



Re: Visual C# General Use string in place of object name to change properties

ARK88

This is my basic response:

Code Snippet
this.Controls[string.Format("foobar{0}", n)].Enabled = true;

My longer response is that it might not be that straight-forward because not all controls are controls of the form. If you add a button to a form, the button is added to the controls collection of the form. If you add a panel to a form, it to is added to the controls collection of the form. But if you add a button to the panel, the button is added to the controls collection of the panel... and the code shown previously would not work. I don't know of a method built into the form class that looks for controls throughout the heirarchy of it's UI. So, if you can guarantee that all the controls you are trying to implement this on are within the same controls collection then the code should work as shown above...





Re: Visual C# General Use string in place of object name to change properties

SyberWizard

Yes, that example worked for the first section that I had in mind. That was an object of System.WIndows.Forms.Label. Thank you, that will allow me to cut out a lot of excess code, always a good thing! With the information you provided, I also tried something similar on a different object. This is an object of System.Windows.Forms.Panel. In this case, I want to make a mass change of the BackColor property, but it did not work. So this time the object is a panel, "foopanel1f". So I tried

this.Controls[string.Format("foopanel{0}f",n)].BackColor = Color.LawnGreen;

and I get a "NullReferenceException was unhandled" "Object reference was not set to an instance of an object."

Is this what you are referring to concerning what collection the object is in How do I determine that These two items, one being a label and the other being a panel, are side by side and appear to me to be in the same container. Or am I way off base





Re: Visual C# General Use string in place of object name to change properties

o00oo00o

Code Snippet

foreach(Control widget in this.Controls)

{

if(widget != null) //this is for taking care of the the null exception.

{

if(widget.GetType().Equals(typeof(Label))) //handles label type only.

{

((Label)widget).BackColor = Color.LawnGreen;

}

}

}

Regards,

Max





Re: Visual C# General Use string in place of object name to change properties

ARK88

I can't answer your question with a yes or a no, because I don't know how your application is structured (from a UI perspective). Additionally, you didn't post enough code for me to pick out any bugs... so here are my comments/questions:

  1. I can only assume that the line of code you posted is within a loop... is that correct
  2. If #1 is true, could you step through the code in that loop and tell me what the value of "n" is when it blows up

Let's start with that...





Re: Visual C# General Use string in place of object name to change properties

SyberWizard

OK, this is stranger than I first thought. I have commented out the original functional "if" statements. If I set numSensors to either 1 or 2, it works fine. If I set it to 3 or more, it blows up. Using the debugger, "i" is incrementing properly, and stepping through, all other objects appear to have the same name as I loop through. These objects were created from a copy of the first one.

private void btnStartScan_Click(object sender, EventArgs e)

{

// Display text beside Progressbar to show program is working

StatusLabel.Visible = true;

// Set bar color for active sensors

for (int i = 1; i <= 12; i++)

{

if (numSensors.Value >= i) this.Controls[string.Format("pnlStatus{0}f", i)].BackColor = Color.LawnGreen;

}

//if (numSensors.Value >= 1) pnlStatus1f.BackColor = Color.LawnGreen;

//if (numSensors.Value >= 2) pnlStatus2f.BackColor = Color.LawnGreen;

//if (numSensors.Value >= 3) pnlStatus3f.BackColor = Color.LawnGreen;

//if (numSensors.Value >= 4) pnlStatus4f.BackColor = Color.LawnGreen;

//if (numSensors.Value >= 5) pnlStatus5f.BackColor = Color.LawnGreen;

//if (numSensors.Value >= 6) pnlStatus6f.BackColor = Color.LawnGreen;

//if (numSensors.Value >= 7) pnlStatus7f.BackColor = Color.LawnGreen;

//if (numSensors.Value >= 8) pnlStatus8f.BackColor = Color.LawnGreen;

//if (numSensors.Value >= 9) pnlStatus9f.BackColor = Color.LawnGreen;

//if (numSensors.Value >= 10) pnlStatus10f.BackColor = Color.LawnGreen;

//if (numSensors.Value >= 11) pnlStatus11f.BackColor = Color.LawnGreen;

//if (numSensors.Value >= 12) pnlStatus12f.BackColor = Color.LawnGreen;





Re: Visual C# General Use string in place of object name to change properties

ARK88

Double-check the panels on your form to make sure you have one named "pnlStatus3f". Also, make sure "pnlStatus3f" is not inside a container control (i.e. it's parent should be the form itself). If you aren't sure if it is within a container other than the form... right-click on it, choose "Cut", find an open spot on the form and right-click, then choose "Paste"... if you then drag "pnlStatus3f" in order to position it somewhere, make sure you don't accidentally drag-and-drop it on a nother panel or container. Let me know what you find...



Re: Visual C# General Use string in place of object name to change properties

SyberWizard

You hit it again. I was becoming suspicious about the "in another container" issue but had not had time to actually check it. Once I moved the panel it started working. The "look" I was going for was a green status bar that, when a sensor was opened, the green would slowly decrease in size, appearing to be turning to yellow. The easiest way I know to show the effect is to put a green panel on top of a yellow panel of the same size, and then change the length of the green panel. I could also had the two panels "nose-to-nose" with the yellow panel size of 0,0 (if it would even let me), but then I've got to change two panels for every adjustment. I could see no reason to double the code size. To resolve the issue, I dragged the top panel to another location, and then manually adjusted the position numbers to the same location (as opposed to just dragging and dropping). It seems to be happy that way.

Still, shouldn't there be some indication when an item is considered to be "in" another item Just knowing this had happened would have saved a lot of troubleshooting. Regardless, thanks for the assistance!





Re: Visual C# General Use string in place of object name to change properties

ARK88

Sometimes you can kind of tell by the dashed line that runs around a control (it kind of gets cut off when it goes outside the parent control), but that doesn't help a whole lot for the situation you described... regardless, I would agree that some type of visual indicator would be nice. What would be even nicer is to have a property in the Property window say who the parent of the control is. Even if that property were read-only it would still be really helpful.



Re: Visual C# General Use string in place of object name to change properties

SyberWizard

I agree with you, it would be very useful to know what the parents of an object are. I have had similar problems in other languages, and knowing I am a babe in the woods, there must be a tremendous number of folks needing this also.

I have always found using loops this way to be real handy to keep code short. Is there a reference book or source that you would recommend that covers using loops this way I've got much to learn, and I suspect this stuff is documented somewhere.

For instance, what all does "this.Controls" provide access to

And what would be the stucture to put variables or constants in a loop For instance, using

if (readData >= BIT_11)

{

bPortStatus[11] = true;

readData = readData - BIT_11;

}

which goes from 0 to 15, could just as easily be many more. A for loop certainly would clean this up!

So I successfully put the local variable bPortStatus[11] into a loop by simply using bPortStatus[(i)], but the constant integer BIT_11 generates an error when entered into a loop as BIT_(i) . It breaks with "The name "BIT_" does not exist in the current context." Correct, and it doesn't exist anywhere else either! I need to grasp why one works and the other breaks, as this project will hopefully take off soon, and I need to get my head wrapped around this.





Re: Visual C# General Use string in place of object name to change properties

ARK88

"Controls" is a collection that contains controls. If a control is a container control, it can have other controls in it. So, a form is a container control, a groupbox is a container control, a panel is a container control, etc... Each of those container controls has a "Controls" collection, which is all the controls contained within it. Remember when you accidentally placed one of your panels inside another If you would have checked the "Controls" collection of the outer panel you would have seen it had one control in its "Controls" collection (the misplaced panel). Its a parent-child type of relationship, where the parent container control can have zero or many child controls.

In your sample code, "bPortStatus" is an array. An array is a list of values. One advantage to arrays is that rather than declaring 15 variables, you can declare one array that has 15 elements (it can cut down on the amount of code you have to write). Specific values in an array are referenced using "[x]" where "x" is the index of the item you want. I'm not sure how you have "BIT_11" defined in your code, but its obvious by your error message that "BIT_" is not defined as an array, which is why you can't use the "[x]" syntax on it.

I can't really direct you to a book for more information on loops structured the way we've been discussing them... everything I've shared with you has been mostly things I've learned "on-the-job". If I were you, I'd look through the Visual Studio help file for more information about arrays, then try to write some code that uses them. After that, you might want to read-up a little bit about the Controls collection, then learn how to loop through them using "for" and "foreach" loops. A good sample application you could write to get you a little more acclimated would be a program that starts with the controls collection on the form, itterates through each control in that collection, then each controls collection of each of those controls, etc... so that it basically traverses every parent-child relationship on the entire form. It will familiarize you more with controls, control collections, loops, and maybe even recursive functions.