Question

I am relatively new to the whole .NET thing, coming from a VB classic background.

On my form I have a tabcontrol, with 4 tabs. Most of the code is handled using a shared handler, but for the others I have to write a handler for each.

How can I optimize these routines into a single procedure?

    Private Sub cboCalc0_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboCalc0.SelectedIndexChanged
    'Page 0
    If (Not (IsNothing(trvSignals0.SelectedNode)) And txtSignalName0.Enabled = True) AndAlso trvSignals0.SelectedNode.Level = 3 Then
        tempChannelProp(0, trvSignals0.SelectedNode.Tag).CalcVariant = cboCalc0.SelectedIndex
    End If
End Sub

Private Sub cboCalc1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboCalc1.SelectedIndexChanged
    'Page 1
    If (Not (IsNothing(trvSignals1.SelectedNode)) And txtSignalName0.Enabled = True) AndAlso trvSignals1.SelectedNode.Level = 3 Then
        tempChannelProp(1, trvSignals1.SelectedNode.Tag).CalcVariant = cboCalc1.SelectedIndex
    End If
End Sub

Private Sub cboCalc2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboCalc2.SelectedIndexChanged
    'Page 2
    If (Not (IsNothing(trvSignals2.SelectedNode)) And txtSignalName2.Enabled = True) AndAlso trvSignals2.SelectedNode.Level = 3 Then
        tempChannelProp(2, trvSignals2.SelectedNode.Tag).CalcVariant = cboCalc2.SelectedIndex
    End If
End Sub

Private Sub cboCalc3_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboCalc3.SelectedIndexChanged
    'Page 3
    If (Not (IsNothing(trvSignals3.SelectedNode)) And txtSignalName3.Enabled = True) AndAlso trvSignals3.SelectedNode.Level = 3 Then
        tempChannelProp(3, trvSignals3.SelectedNode.Tag).CalcVariant = cboCalc3.SelectedIndex
    End If
End Sub

I have handled the other bits as follows, and it works great, but I just cannot figure out how to do it with code like that above.

    Private Sub trvSignals_AfterCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles trvSignals0.AfterCheck, trvSignals1.AfterCheck, trvSignals2.AfterCheck, trvSignals3.AfterCheck
    'Handles Page 0,1,2,3
    sender.SelectedNode = e.Node
    If e.Node.Level = 3 Then
        tempChannelProp(sender.tag, e.Node.Tag).Active = e.Node.Checked
    End If
End Sub

I use the tag property of the control of each page to hold either 0,1,2 or 3 as appropriate.

Thanks

Graham

Was it helpful?

Solution

Create control arrays that you can reference by index, and put the index in each controls' Tag.

Class MyForm

    Private ReadOnly cboCalcArray As ComboBox()
    Private ReadOnly trvSignalsArray As TreeView()
    Private ReadOnly txtSignalNameArray As TextBox()

    Public Sub New()
        InitializeComponent()
        cboCalcArray = new ComboBox() {cboCalc0, cboCalc1, cboCalc2, cboCalc3}
        trvSignalsArray = new TreeView() {trvSignals0, trvSignals1, trvSignals2, trvSignals3}
        txtSignalNameArray = new TextBox() {txtSignalName0, txtSignalName1, txtSignalName2, txtSignalName3}
    End Sub

    Private Sub cboCalcX_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) _
        Handles cboCalc0.SelectedIndexChanged, 
                cboCalc1.SelectedIndexChanged, 
                cboCalc2.SelectedIndexChanged, 
                cboCalc3.SelectedIndexChanged
        Dim index As Integer = sender.Tag
        If (Not (IsNothing(trvSignalsArray(index).SelectedNode)) And txtSignalNameArray(index).Enabled = True) AndAlso trvSignals2.SelectedNode.Level = 3 Then      
            tempChannelProp(index, trvSignalsArray(index).SelectedNode.Tag).CalcVariant = cboCalcArray(index).SelectedIndex      
        End If      
    End Sub
End Class

OTHER TIPS

You can leverage a couple of features:

1) The VB Handles statement can hook multiple control events to the same method.

2) You can get the combobox from the sender, then extract the index.

3) From the index, you can find the other associated controls.

Private Sub cboCalc_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboCalc0.SelectedIndexChanged, cboCalc1.SelectedIndexChanged, cboCalc2.SelectedIndexChanged, cboCalc3.SelectedIndexChanged

    Dim oCombo As ComboBox

    oCombo = DirectCast(sender, ComboBox)

    Dim wIndex As Integer
    Dim oTree As TreeView
    Dim oTextBox As TextBox

    wIndex = CInt(oCombo.Name.Substring(oCombo.Name.Length - 1))

    oTree = DirectCast(Me.Controls.Find("trvSignals" & wIndex.ToString, True)(0), TreeView)
    oTextBox = DirectCast(Me.Controls.Find("txtSignalName" & wIndex.ToString, True)(0), TextBox)

    If oTree.SelectedNode IsNot Nothing AndAlso oTextBox.Enabled AndAlso oTree.SelectedNode.Level = 3 Then
        tempChannelProp(wIndex, oTree.SelectedNode.Tag).CalcVariant = oCombo.SelectedIndex
    End If

End Sub

There is likely a more elegant solution to your problem somewhere. I find that, if I am defining the same controls and methods for multiplpe tabs on a tab control, it might be time to examine my design . . . Not always, though. :-)

This might be a little less clumsy, although using Select Case to choose between otherwise identical configurations of UI elements gives me the heebie-jeebies (It DOES get all your code into one handler, however):

    Private Sub PerformCalcs(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles _
        cboCalc0.SelectedIndexChanged,
        cboCalc1.SelectedIndexChanged,
        cboCalc2.SelectedIndexChanged,
        cboCalc3.SelectedIndexChanged

        Dim cboCalc As ComboBox = DirectCast(sender, ComboBox)

        ' The Parent of the combo box is the TabPage, and the Parent of the TabPage is the TabControl:
        Dim t As TabControl = cboCalc.Parent.Parent

        Dim SelectedNode As TreeNode
        Dim TxtSignalName As TextBox

        ' The TabControl knows the index value of the currently selected tab:
        Select Case t.SelectedIndex
            Case 0 'Page 0
                SelectedNode = trvSignals0.SelectedNode
                TxtSignalName = txtSignalName0
            Case 1 ' Page 1
                SelectedNode = trvSignals1.SelectedNode
                TxtSignalName = txtSignalName1
            Case 2 ' Page 2
                SelectedNode = trvSignals2.SelectedNode
                TxtSignalName = txtSignalName2
            Case 3 ' Page 3
                SelectedNode = trvSignals3.SelectedNode
                TxtSignalName = txtSignalName3
            Case Else ' Ooops! Something horrible happened!
                Throw New System.Exception("You have passed an invalid Control as a parameter")
        End Select

        If (Not (IsNothing(SelectedNode)) And TxtSignalName.Enabled = True) AndAlso trvSignals3.SelectedNode.Level = 3 Then
            tempChannelProp(3, SelectedNode.Tag).CalcVariant = cboCalc.SelectedIndex
        End If

    End Sub
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top