Results 1 to 9 of 9

Thread: Help condensing repetative code

  1. #1

    Thread Starter
    New Member
    Join Date
    May 2013
    Posts
    11

    Help condensing repetative code

    I had 2 questions, I need to Gray out 48 text boxes on Run of the program. And keep them grayed unless the user makes a selection to enter their own criteria via a selection within a ComboBox.

    My first question, and I hope by the text below you can make sense of how repetitive this is going to become and what it is I'm trying to do. I will have to write the If Statements over and over and was wondering if I could condense these since the code will be so repetitive.

    Also The Read only statements in class level of the Form_Load, is there anyway to condense these other than putting them all in a function to call on? Since I will have to write ReadOnly statements for 48 TextBoxes.

    Code:
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            txtQuadEx.ReadOnly = True
            txtQuadReps.ReadOnly = True
            txtQuadSets.ReadOnly = True
    
            txtUniQuadEx.ReadOnly = True
            txtUniQdReps.ReadOnly = True
            txtUniQdSets.ReadOnly = True
    
        End Sub
    
        Private Sub cboQuadEx_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboQuadEx.SelectedIndexChanged
            If cboQuadEx.Text = "Enter My Own Exercise" Then
                txtQuadEx.ReadOnly = False
            Else
                txtQuadEx.ReadOnly = True
            End If
    
        End Sub
    
    
        Private Sub cboQuadReps_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboQuadReps.SelectedIndexChanged
            If cboQuadReps.Text = "Enter My Own Reps/Sets" Then
                txtQuadReps.ReadOnly = False
                txtQuadSets.ReadOnly = False
    
            Else
                txtQuadReps.ReadOnly = True
                txtQuadSets.ReadOnly = True
    
            End If
    
        End Sub
    
        Private Sub cboUniQuadEx_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboUniQuadEx.SelectedIndexChanged
            If cboUniQuadEx.Text = "Enter My Own Exercise" Then
                txtUniQuadEx.ReadOnly = False
            Else
                txtUniQuadEx.ReadOnly = True
            End If
    
        End Sub
    
        Private Sub cboUniQuadReps_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboUniQuadReps.SelectedIndexChanged
            If cboUniQuadReps.Text = "Enter My Own Reps/Sets" Then
                txtUniQdReps.ReadOnly = False
                txtUniQdSets.ReadOnly = False
    
            Else
                txtUniQdReps.ReadOnly = True
                txtUniQdSets.ReadOnly = True
    
            End If
        End Sub
    Last edited by Graffix; May 15th, 2013 at 09:01 PM.

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Help condensing repetative code

    To start with, just set the ReadOnly properties of the TextBoxes in the designer, so the code in the Load event handler is not required. You can then create a relationship between the ComboBoxes and the TextBoxes, e.g. using a Dictionary. You can then create a single event handler for the SelectedIndexChanged or SelectionChangeCommitted events of all the ComboBoxes and write generic code that will work for all TextBoxes, e.g.
    Code:
    Private textBoxesByComboBox As New Dictionary(Of ComboBox, TextBox())
    
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'TextBox1 is associated with ComboBox1.
        'TextBox2 and TextBox3 are associated with ComboBox2.
        textBoxesByComboBox = New Dictionary(Of ComboBox, TextBox()) From {{ComboBox1, {TextBox1}},
                                                                           {ComboBox2, {TextBox2, TextBox3}}}
    End Sub
    
    Private Sub ComboBoxes_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox2.SelectionChangeCommitted,
                                                                                              ComboBox1.SelectionChangeCommitted
        Dim comboBox = DirectCast(sender, ComboBox)
        Dim textBoxes = textBoxesByComboBox(comboBox)
        Dim [readOnly] = Not comboBox.Text.StartsWith("Enter My Own")
    
        For Each textBox As TextBox In textBoxes
            textBox.ReadOnly = [readOnly]
    
            If [readOnly] Then
                textBox.Clear()
            End If
        Next
    End Sub
    Note that some of that syntax requires VB 2010 or later but you can still accomplish the same thing with slightly longer code in earlier versions. Also, note that the SelectionChangeCommitted is only raised when the user makes a selection via the UI while SelectedIndexChanged is raised whenever the SelectedIndex changes. Sometimes either will do but sometimes one is more suitable than the other.
    Last edited by jmcilhinney; May 15th, 2013 at 10:27 PM. Reason: Added 'Not' to 'readOnly' calculation. Added code to clear TextBox if read-only.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3

    Thread Starter
    New Member
    Join Date
    May 2013
    Posts
    11

    Re: Help condensing repetative code

    I really appreciate the info jmcilhinney, I'm still pretty fresh with my VB understanding and have never worked with a dictionary in the past. But based off of your code and some research I'm doing on my own I will certainly give that a shot and post any issues I might run into. Thanks again.

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Help condensing repetative code

    You may be able to find this out on your own and may have already done so but, with regards to the Dictionary class, it is intended to be able to store data against a set of unique keys. Much as you can open a conventional dictionary and quickly look up a word to find it's meaning, so you can provide a key and quickly get the corresponding data from a .NET Dictionary object.

    Early versions of .NET included only the Hashtable class, which performed the same function but both the keys and values were stored as Object references. With the introduction of generics in .NET 2.0, the Dictionary(Of TKey, TValue) class was introduced to supersede the Hashtable. Hashtable still exists but should not be used in new code. The generic Dictionary allows you to fix the type of the keys and the values. In this case the keys are the ComboBoxes and the values are arrays of TextBoxes. Specifying the values as TextBox arrays rather than TextBoxes allows you to associate more than one TextBox with each ComboBox, which you appear to require.

    In case it's unclear, this code:
    Code:
    textBoxesByComboBox = New Dictionary(Of ComboBox, TextBox()) From {{ComboBox1, {TextBox1}},
                                                                       {ComboBox2, {TextBox2, TextBox3}}}
    is functionally equivalent to this:
    Code:
    textBoxesByComboBox = New Dictionary(Of ComboBox, TextBox())
    
    textBoxesByComboBox.Add(ComboBox1, New TextBox() {TextBox1})
    textBoxesByComboBox.Add(ComboBox2, New TextBox() {TextBox2, TextBox3})
    By the way, in my original code, I was creating two Dictionaries where only one was required. This:
    Code:
    Private textBoxesByComboBox As New Dictionary(Of ComboBox, TextBox())
    should have just been this:
    Code:
    Private textBoxesByComboBox As Dictionary(Of ComboBox, TextBox())
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  5. #5
    PowerPoster Nightwalker83's Avatar
    Join Date
    Dec 2001
    Location
    Adelaide, Australia
    Posts
    13,344

    Re: Help condensing repetative code

    If you code is the same for each event you code put the code in its own function then code each function from the appropriate event.
    when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
    If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
    https://get.cryptobrowser.site/30/4111672

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Help condensing repetative code

    Quote Originally Posted by Nightwalker83 View Post
    If you code is the same for each event you code put the code in its own function then code each function from the appropriate event.
    Not much point having separate event handlers at all if they are all going to do the same thing. Not such a bad idea to call a method from the event handler though. It's good practice to not put any code in event handlers other than calls to your own methods so the purpose of the code is clearer but having multiple event handlers that all do exactly the same thing, whether it be call the same single method or not, is a bit wasteful.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  7. #7

    Thread Starter
    New Member
    Join Date
    May 2013
    Posts
    11

    Re: Help condensing repetative code

    Thank you again for all the assistance. Alright after watching some vids and reading your description, I'm not sure if this is ideal to what I'm trying to do. Picture this: I have 4 tabs, all 4 tab pages contain 8 combo boxes, 4 of the 8 will turn a text boxes ReadOnly to False, and the remaining 4 will turn 2 text boxes ReadOnly to False, when a certain option is selected from the user within a combo box. I supposed I will just need to include if else statements as I've got above because I will need to set up if else statements for the remaining items. I am going to try condensing my code on a few and post it up to see if this will be optimal. Again thank you much.

    Also is there a way to disable typing in a combobox that wont wipe the text that is displayed when the program runs? What I'm trying to do is have the combobox read a certain text when the program is run but not allow a user to type in the box.

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Help condensing repetative code

    Quote Originally Posted by Graffix View Post
    Thank you again for all the assistance. Alright after watching some vids and reading your description, I'm not sure if this is ideal to what I'm trying to do. Picture this: I have 4 tabs, all 4 tab pages contain 8 combo boxes, 4 of the 8 will turn a text boxes ReadOnly to False, and the remaining 4 will turn 2 text boxes ReadOnly to False, when a certain option is selected from the user within a combo box. I supposed I will just need to include if else statements as I've got above because I will need to set up if else statements for the remaining items. I am going to try condensing my code on a few and post it up to see if this will be optimal. Again thank you much.
    Unless I'm misunderstanding you, you don't need If...Else statements. Look at what I did in post #2.
    Code:
        Dim [readOnly] = Not comboBox.Text.StartsWith("Enter My Own")
    
        For Each textBox As TextBox In textBoxes
            textBox.ReadOnly = [readOnly]
    The event will be raised every time the selection changes and that 'readOnly' variable will be set to False if the current selection starts with "Enter My Own" and True if it doesn't. That variable is then assigned to the ReadOnly property of each associated TextBox. That means that the ReadOnly property of the associated TextBoxes will be set every time the selection changes in a ComboBox and it will only be set to False, thus allowing text to be entered, if the selection starts with "Enter My Own". That sounds like exactly what you want to me.
    Quote Originally Posted by Graffix View Post
    Also is there a way to disable typing in a combobox that wont wipe the text that is displayed when the program runs? What I'm trying to do is have the combobox read a certain text when the program is run but not allow a user to type in the box.
    Unless you set Enabled to False, the user can type anything into a ComboBox whose DropDownStyle is set to DropDown and only select from the drop-down list if DropDownStyle is DropDownList.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  9. #9

    Thread Starter
    New Member
    Join Date
    May 2013
    Posts
    11

    Re: Help condensing repetative code

    Thanks jmcilhinney, I understand what you are saying now just a bit of a learning curve on my end.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width