I Need help: Editing objects at runtime Dynamically

lickuid

Active member
Joined
Nov 6, 2006
Messages
37
Programming Experience
Beginner
I posted this in another forum, but realized it wasn't the one I originally inteded to, sorry.

In other languages, I can edit the properties of objects at runtime with no problem. I'm sure there's a way to do this with vb.net but I've yet to find the syntax for what I'm looking for. So essentially, what I'm trying to do is this:

For dim inc = 0 to 10
["objectName" & inc].visible = true
next

This is simply an example of what I'm trying to do. Basically, I have a group of 10 objects with the name "objectName" in common, the only thing that differs, of course, are the numbers. Is there any way I can do this in vb? If it'd be possible, I could alter the properties of a button or whatever at runtime as long as I enter the buttons name in a text field or something like that. I'm trying to add a bit of dynamics (and optimized code) to my apps.
 
Nevermind the help. A little trial and error did the trick for me. In case someone else is wondering, the solution would be:

for dim ii as integer = 0 to 10 step 1 'mind you, if you don't have an object who's name is objectName0, you'll get an error. If you start at objectName1, ii should = 1
Me.Controls.Item("objectName" & ii).visible = true
next

:)
 
I posted this in another forum, but realized it wasn't the one I originally inteded to, sorry.

Have you caused a duplicate thread? you should report the other thread to the moderation team (click the
report.gif
icon in the top right) so it can be removed. If there are no other replies, then you can delete it yourself in the EDIT page of the first post in the thread

I'm trying to add a bit of dynamics (and optimized code) to my apps.
I'm not sure that you can have something that is both dynamic and optimized..


Your solution below actually relies on a simple thing called a collection. All the items in the collection called Controls are of type Control and hence can be manipulated as though they are controls. You have the option of creating other collections so that you can alias your existing controls:

Dim buttons as System.Collections.Generic.Dictionary(Of String, Button)

buttons("button0") = btnOK
buttons("button1") = btnCancel


Now, you can refer to these buttons in a loop without having to have them named in an illogical fashion.

If youre not going to have any special groupings of buttons within your dictionary.. i.e. youre going to have:
button0
button1
button2
button3
button4

and not:
toolbarbutton0
toolbarbutton1
actionButton0
actionButton1
dismissButton0

etc, then you would be better off using an array becuse it would be a far lower overhead. If your collection is to grow dynamically, use a List, if your colelction is going to hold "groups" of buttons distincted by the start of their name, you can choose Dictionary.


Other options you have are iterating the Form.Controls collection and examining the type with either TypeOf or GetType:
If TypeOf Me.Controls(0) Is Button Then...
If Me.Controls(0).GetType() Is GetType(Button) Then

Use the former when you want to determine if the control is descended from the type you gave. Use the latter when you want to determine if the control is exactly what you gave.

If TypeOf myTextBox Is TextBoxBase Then 'evaluates TRUE, TB is descended from TBB
If myTextBox.GetType() Is GetType(TextBoxBase) Then 'evaluates FALSE, TB is not directly a TBB
 
Thanks Cjard,

Okay, I'm really trying to wrap my head around what you wrote and put it to practice...

Dim buttons as System.Collections.Generic.Dictionary(Of String, Button)

buttons("button0") = btnOK
buttons("button1") = btnCancel
I tried this, and got a null reference exception. Since btnOK and btnCancel aren't quoted, I'm assuming they're actual hard-coded buttons that the buttons collection is referencing. Is it the case, then, that if you were to type :
buttons("button0").enabled = false
, that btnOK would then be affected?

etc, then you would be better off using an array becuse it would be a far lower overhead. If your collection is to grow dynamically, use a List, if your colelction is going to hold "groups" of buttons distincted by the start of their name, you can choose Dictionary.
Could you give me an example of how to assign a group of buttons to an array?
Also, i think it would help if I tell you I'm working with checkboxes, although I can apply what you're saying to that.

when I tried to use Me.Controls("CheckBox1"), there was no ".Checked" feature there. I suppose that vb provides only the universal methods and values of each Windows.Forms class types... how can I make the checkbox checked?
 
Thanks Cjard,

Okay, I'm really trying to wrap my head around what you wrote and put it to practice...

I tried this, and got a null reference exception.

Maybe the dictionary object is null.. try adding the word NEW in:

Dim buttons as NEW System.Collections.Generic.Dictionary(Of String, Button)

Sorry about that.. minor syntax err, i assure you :)

Since btnOK and btnCancel aren't quoted, I'm assuming they're actual hard-coded buttons that the buttons collection is referencing. Is it the case, then, that if you were to type :
buttons("button0").enabled = false
, that btnOK would then be affected?

Yep, they are indeed the actual button object names. It saves you having to call your buttons button1, button2, etc which isnt very good descriptive practice (even though they are named default thus by the IDE)


Could you give me an example of how to assign a group of buttons to an array?

Dim myButtonArray(0 to 9) as New Button()
myButtonArray(0) = btnOK
myButtonArray(1) = btnCancel

Also, i think it would help if I tell you I'm working with checkboxes, although I can apply what you're saying to that.

when I tried to use Me.Controls("CheckBox1"), there was no ".Checked" feature there.

Because Me.Controls is a collection that holds objects of type Control. Checkbox is descended from Control and is hence capable of existing in a collection of Controls but when it is retrieved from the collection, it will be boxed up as a Control. You need to cast it into a Checkbox again:

DirectCast(Me.Controls("Checkbox1"), Checkbox).Checked = true

Bold bit = the casting



If you dont know much about inheritance and boxing, look it up. Its analogous to christmas presents - all wrapped in the same paper. All of type "Gift". You must remove the wrapping to see what it really is. Casting removes the wrapping.

Taking this a little further, everything is descended from object, sometimes multiple levels of inheritance like a family tree. children are capable of behaving like their ancestors.. A child can be cast into any one of its ancestors and back to itself again, but it cannot be cast into one of its children or one of its siblings in any inherited branch
 
Jeeze! Wow! Thanks, I never thought of trying to Cast the type! Tanks... I've casted variables often in php and action script but it never dawned on me to try to cast objects... You're Brilliant! Thanks again!

I'll do my research an homework on inheritance and boxing, (although anyone can feel free to add a useful link for future viewers reference, when I come across one, I'll post as well). I think it will take some time before I have an understanding of it all as you do. Thanks again cjard!
 
I tried the direct cast... and it worked.. the actual object collection was in a group box so if anyone comes across this wondering the same thing I was..
Public chkArray(19) As CheckBox

Sub.....
For ii As Integer = 0 To 19 Step 1
Dim nn = ii + 1
chkArray(ii) = Me.Controls.Item("GroupBox1").Controls.Item("CheckBox" & nn)
Next
End Sub
 
Jeeze! Wow! Thanks, I never thought of trying to Cast the type! Tanks... I've casted variables often in php and action script but it never dawned on me to try to cast objects...

A quick note at this point, to outline the difference between casting and converting.. Cast can only be applied to type. To change an object to another unrelated type we actually convert it..

"123" as a string -> 123 as an integer is a conversion
Textbox -> Control is a cast.

As noted before, any object in a program is descended from Object. It can be cast into any one of its ancestors.

As to what it can be converted to depends on whether a conversion exists for the from and to. String to Integer is a favourite.. it actually requires coding effort to convert the sequence of characters into a number


When discussing casting and converting be sure to get the correct terms to avoid confusing people..
 
A good article on the differences can be found Here

It's worth a read because the following two statements are equal in terms of the output

VB.NET:
Dim Tb as Textbox = Ctype(Object, TextBox)
 
Dim Tb as Textbox = Directcast(Object, Textbox)


However the Ctype statement will go digging around in the VisualBasic.Dll for the runtime helpers it needs to be able to determine if the conversion is valid. Whereas the Directcast operator does not and that is where performance is improved. Check out the article, it's short but informative. Ctype is not your best friend in terms of performance, as previously stated all of the runtime helpers are in VisualBasic.dll for converting things to and from object etc..
 
Annoyingly, the VB iDE uses CType almost exclusively when autogenerating code.. I hope its at least optimised so that it does a gettype first and if it determines there is no conversion required, performs a cast instead
 
Back
Top