Mafu Josh
Mafu Josh

Reputation: 2672

VB.NET one-liner set property on item in dynamic array

In VB.NET, on one line of code, dynamically create an array based on some already existing TextBox objects, select one textbox by index, and set its Text property.

Example on two lines:

Dim textboxes = {TextBox1, TextBox2, TextBox3}
textboxes(someIndex).Text = "abc"

Syntax error trying one line:

{TextBox1, TextBox2, TextBox3}(someIndex).Text = "abc"

Just looking for the cleanest one-liner.

I occasionally run into different forms of this. I used TextBox to keep the question simpler. It could be objects that aren't controls and aren't named similarly, such as like:

{itemDefault, itemFromSql, itemFromXml}(someIndex).SomeProperty = someValue

(And I'm not asking for reasons to instead make this more than one line of code.)

Upvotes: 0

Views: 406

Answers (6)

Darryl
Darryl

Reputation: 6217

Edit: Bad answer - this doesn't work as a stand-alone statement!!!

How about this:

(New TextBox() {TextBox1, TextBox2, TextBox3})(someIndex).Text = "abc"

Upvotes: 0

Mafu Josh
Mafu Josh

Reputation: 2672

Enumerable to the rescue!

Enumerable.ElementAt({TextBox1, TextBox2, TextBox3}, someIndex).Text = "abc"

Another cool function I discovered is Enumerable.ElementAtOrDefault(), which returns the datatype's default value (such as null) if the index is out of range of the array.

Upvotes: 2

Mafu Josh
Mafu Josh

Reputation: 2672

Technically VB's Choose() function would work, except it has a stench of being backwards compatible with some ancient version of BASIC, due to its index being 1-based, and a datatype of Single for some reason... And also its return object would have to be wrapped in CType or DirectCast...

A solution based stone's suggestion of creating a wrapper function, and also closely and generically imitating VB's Choice() function:

Public Shared Function Choose(Of T)(index As Integer, ParamArray choice As T()) As T
    Return choice(index)
End Function

Which can then be called like:

Choose(someIndex, TextBox1, TextBox2, TextBox3).Text = "abc"

Upvotes: 0

David
David

Reputation: 6111

Simply set the properties during the initialization:

Dim textboxes() As TextBox = {New TextBox() With {.Text = "abc"}, New TextBox() With {.Text = "def", 'etc...}

Update I see in your comment that the TextBox controls are already created; I misunderstood, I thought that the TextBox controls were also being created dynamically.

You aren't able to do this during the initialization of the array. Simply put, you cannot access the members of the collection before the collection is created.

If I had to guess as to why casting the collection first works, it may be that casting the array completes the initialization allowing you to access its members.

Upvotes: 1

Visual Vincent
Visual Vincent

Reputation: 18310

If these are all located within your form you could look for them by name (that is, assuming that all of them have the name TextBox# - where # is the number 1, 2, 3, and so on):

Me.Controls.Find("TextBox" & (someindex + 1), True)(0).Text = "abc"

However note that if you give it an index that results in a name of a text box that doesn't exist, this will throw a NullReferenceException.

Upvotes: 1

Mafu Josh
Mafu Josh

Reputation: 2672

The best solution I can think of is to wrap the array in some other call, such as CType() or DirectCast(), which works but its purpose isn't clear to others.

DirectCast({TextBox1, TextBox2, TextBox3}, TextBox())(someIndex).Text = "abc"

Upvotes: 2

Related Questions