views:

448

answers:

5

I have a sub that handles when 14 ComboBoxes have their Index changed. I am able to cast the sender of the event, and obtain properties from there. However, after that, I want to be able to change the properties of the actual sender, rather than the cast one. How would I do this?

Current code:

Private Sub ComboBoxIndexChange(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged, ComboBox2.SelectedIndexChanged [etc]
        Dim myComboBox As ComboBox = sender

        Select Case myComboBox.Text
            Case "Will"
                Me.Controls(myComboBox.Name).Text = "555-555-555"
            Case "Bob"
                Me.Controls(myComboBox.Name).Text = "555-124-1234"
            [etc]
        End Select
    End Sub
End Class

As you can see, I am currently trying to use

Me.Controls(myComboBox.Name).Text

But I get the error: Object reference not set to an instance of an object.

What can I do?

+1  A: 

ComboBox is a reference type, so if you assign directly to the Text property of the myComboBox variable, it will update the control.

Christian Hayter
Thank you, I had no idea it was a reference. I have just done some debugging and it does in fact change the text property of the ComboBox, but instantly after it it changed back to it's original value (in this case "Will"). Any idea what is happening?
blake
@blake: it's not a good idea to set the `Text` property in a combo box in the `SelectedIndexChanged` event; when the user selects an item in the list, the control will automatically set the `Text` to the text of the selected item.
Fredrik Mörk
In what event could I change it then? All I want is for the user to choose the name of the person in the Combo Box, which then appears as their telephone number.
blake
I would need more information about your debugging session to answer that. Maybe the variable is now pointing to a different control? Maybe another event is resetting the Text property?
Christian Hayter
@blake: I would find that behavior rather confusing, as a user. Perhaps you should include the phone number in the text in the list instead, as `"Will (555-555-555)"`. The other option is to make the ComboBox OwnerDrawed, but that will be rather complex.
Fredrik Mörk
Ah, I see. In my opinion you should not be using one UI widget to display two different pieces of data, but if you want to stick with that design, then you will have to sprinkle a lot of safety checking code around several different event handlers.
Christian Hayter
I think a two object solution will be much easier for everyone ;)
blake
+2  A: 

The sender parameter in an event handler will (typically) contain a reference to the object that raised the event. In the case of the SelectedIndexChanged event of a ComboBox control, it will be the ComboBox that had its SelectedIndex property changed. So in your code sample above myComboBox is referring the ComboBox that raised the event.

To clarify: if you select an item in the drop-down list of a ComboBox control, so that it raises the SelectedIndexChanged event, the sender parameter of the event handler will be that same ComboBox, not a copy of it. This is true for all reference types.

Had it been a value type raising the event it would have been a completely different story, but that is a very rare case (it it is never the case when it comes to controls on a form).

Fredrik Mörk
A: 

This should work:

 Dim ctl As Control
 Dim cmb As ComboBox

 For Each ctl In Me.Controls
   If sender Is ctl Then
     cmb = ctl
     cmb.Text = "string"
     End If
   Next ctl

You can add the specific string assignment code in place of cmd.Text = "string". Assigning cmb allows you to use the specific combobox properties rather than the generic control properties.

xpda
A: 

To answer the original question of why you were getting a null object reference exception, is the Control you are searching for a direct child of the Form? Does it sit in a panel or some other container on the form? If so then I don't think you will find that control in the Form's Controls collection. So this line:

Me.Controls(myComboBox.Name).Text

Only searches through the forms direct children and not recursively through the children of those controls.

Christian Pena
A: 

If I using the following code, I will get the same err: Object reference not set to an instance of an object.

Me.Controls(TBName).DataBindings.Add("Text", dt, dt.Columns(colindex).ColumnName)

Sugestion from Christian Pena fit my case, so the right code should be:

Me.TCAll.TabPages(0).Controls(TBName).DataBindings.Add("Text", dt, dt.Columns(colindex).ColumnName)
ZhanZF