Solved

Textbox Tag's and Strings

Posted on 2004-04-23
14
451 Views
Last Modified: 2010-04-24
Hello,

After getting some advice I got this code to create as many labels/textboxes at run-time equal to the database fields I have loaded into a listbox.

There are two panels, Panel3 and Panel2. Panel3 holds all the run-time generated labels/textboxes and panel2 just holds panel3 so Panel2 can have scroll bars activated once Panel3 get's too large.

    Private Sub Form1_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.SizeChanged
        Me.Panel3.Width = Me.Panel2.Width - 40
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        addTextBox()
    End Sub

Private Sub addTextBox()

        Dim counter As Integer
        counter += 1

        Dim ht As Integer = 0
        For counter = 0 To lstSelection.Items.Count - 1     '<------------ Listbox
            lstSelection.SelectedIndex = counter.ToString
            Dim TextBox As New System.Windows.Forms.TextBox()
            Dim Label As New System.Windows.Forms.Label()

            With Label
                Label.Name = "lblSeach " & counter + 1
                Label.Dock = DockStyle.Bottom
                Label.Text = lstSelection.SelectedItem & ":"
                Me.Panel3.Controls.Add(Label)
            End With

            With TextBox
                Label.Tag = counter
                TextBox.Anchor = AnchorStyles.Left Or AnchorStyles.Right
                TextBox.Name = "txtSearch " & counter + 1
                TextBox.Dock = DockStyle.Bottom
                Me.Panel3.Controls.Add(TextBox)
               
            End With

            ht += Label.Height
            ht += TextBox.Height

        Next
        Panel3.Height = ht

    End Sub

That being said, I read that using the Tag property will let the application know which run-time generated textbox has information typed into it.

I'm using a string from a special database program with API functions this sub can be altered in any way based on your solutions:

 Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        For i = 0 To lstSelection.Items.Count - 1

            Dim strSearch As String

            lstSelection.SelectedIndex = i  'Read through list box
'String -----> strSearch &= "{" & cboTemplate.SelectedItem & ":[" & lstSelection.Items(i).ToString & "]" & _
                        "=" & txtSearch.Text & "}" & "|"  

        Next
 End Sub

If you were to put strSearch into a messagebox an example of this search with several fields would look like:

{TemplateName:[Last Name]=MyLastName}|{TemplateName:[Address]=MyAddress}|{TemplateName:[First Name]=MyFirstName}

Where:

[Last Name] is a database field
MyLastName is somebody's last name (later to be substituted by a textbox hopefully)

The way I know from the user whose last name they are looking for is having them input it in a textbox.
Ok since we are naming our textboxes generic names from your code like:

            With TextBox
                Label.Tag = counter
                TextBox.Anchor = AnchorStyles.Left Or AnchorStyles.Right
                TextBox.Name = "txtSearch " & counter + 1
                TextBox.Dock = DockStyle.Bottom
                Me.Panel3.Controls.Add(TextBox)
               
            End With

Is there a way to tie together for example, the 3rd textfield   say txtSearch3     with the third  database field that is loaded into the listbox so that if I type something into txtSearch3 my search string will know precisely where to put in my long string:

{TemplateName:[Last Name]=MyLastName}|{TemplateName:[Address]=MyAddress}|{TemplateName:[First Name]=txtSearch3.Text}
                                                                                                                                                                         
If I also typed in a search criteria, say for Field #1 then it will look like:

{TemplateName:[Last Name]=txtSearch1.Text}|{TemplateName:[Address]=MyAddress}|{TemplateName:[First Name]=txtSearch3.Text}

Any ideas?

Thanks!

Chris
                                                       

0
Comment
Question by:Trancedified
  • 8
  • 6
14 Comments
 
LVL 14

Expert Comment

by:ptakja
ID: 10902834
Chris,

Note sure if I totally understand your question, but let me take a stab at it.  Basically, you want to query the Tag field of a text box when it's data has been changed to determine where to stuff the info into your long string?

If that is the case, I would suggest putting your textbox objects in an array and having a single event handler for the TextChanged event ( or some other Textbox event you want to handle) for all the textboxes:

So using your code example above, modify it like this:

' Define a class-level scoped arraylist variable to hold your textboxes.
Private aTxtBoxes as ArrayList

Private Sub addTextBox()

        Dim counter As Integer
        counter += 1

        Dim ht As Integer = 0
        For counter = 0 To lstSelection.Items.Count - 1     '<------------ Listbox
            lstSelection.SelectedIndex = counter.ToString
            Dim TextBox As New System.Windows.Forms.TextBox()
            Dim Label As New System.Windows.Forms.Label()

            With Label
                Label.Name = "lblSeach " & counter + 1
                Label.Dock = DockStyle.Bottom
                Label.Text = lstSelection.SelectedItem & ":"
                Me.Panel3.Controls.Add(Label)
            End With

            With TextBox
                Label.Tag = counter
                TextBox.Anchor = AnchorStyles.Left Or AnchorStyles.Right
                TextBox.Name = "txtSearch " & counter + 1
                TextBox.Dock = DockStyle.Bottom
                Me.Panel3.Controls.Add(TextBox)

            End With

            '*****************************
            'Add TextBox to the array
            aTxtBoxes.Add(TextBox)

            ' Wire up event handler for the text box to the routine defined below.
            AddHandler TextBox.TextChanged, AddressOf TextBox_EventHandler
            '*****************************
            ht += Label.Height
            ht += TextBox.Height

        Next
        Panel3.Height = ht

    End Sub

    Private Sub TextBox_EventHandler(sender As System.Object, e As System.EventArgs)
         ' Cast Sender object to a Textbox.  Sender will be the object that triggered this event.  You know it is
         '  a textbox because you wired the event to this routine in the addTextbox routine above.

         Dim txtBox as TextBox = CType(sender, TextBox)

          ' Now case out the Tag property and take whatever action you need
         Select Case txtBox.Tag
              Case 0                       'User edited Textbox #0
                       'Put your code here to edit your long string based on textbox 0's contents.
              Case 1                       'User edited Textbox #1

         End Select

    End Sub

Hope that helps.

Jeff
0
 
LVL 1

Author Comment

by:Trancedified
ID: 10903299
Jeff,

Doing multiple things at once ... I read through  your code looks "doable" and i'll have to try it, i'll just have a lot of Case's there might be over 30 cases (if there is another way to do it?)

1st question though: Your sample works if let's say Textbox #0 and TextBox #1 has been edited right?

2nd:

> Note sure if I totally understand your question, but let me take a stab at it.  Basically, you want to query the Tag field of a >text box when it's data has been changed to determine where to stuff the info into your long string?

You're on the right track.... but will the app "know enough" where to put txtSearch0 or txtSearch1 into this search string?

Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        For i = 0 To lstSelection.Items.Count - 1

            Dim strSearch As String
            lstSelection.SelectedIndex = i  'Read through list box strSearch &= "{" & cboTemplate.SelectedItem & ":[" &
                        lstSelection.Items(i).ToString & "]" & _
                        "=" & txtSearch0.Text & "}" & "|"  
        Next
 End Sub

So in other words:
From each Case.....since I have a For i = 0 To lstSelection.Items.Count - 1 can I keep building a strSearch and keep adding and adding if 2 textboxes were edited per se?

So that eventually strSearch will look like:
{TemplateName:[Last Name]=txtSearch0.Text}|{TemplateName:[First Name]=txtSearch1.Text}

I guess I'm not understanding where the Tag property comes into play when it's inserted into the strSearch string, if at all.

Excellent example, Jeff I'll have play with it further, but I just had some initial questions.

Thanks!

Chris




0
 
LVL 14

Expert Comment

by:ptakja
ID: 10903391
Chris:

>> 1st question though: Your sample works if let's say Textbox #0 and TextBox #1 has been edited right?
 Yes.

2>   what I was thinking was adding your text to your search string in the case statement like this:

  Private Sub TextBox_EventHandler(sender As System.Object, e As System.EventArgs)
         ' Cast Sender object to a Textbox.  Sender will be the object that triggered this event.  You know it is
         '  a textbox because you wired the event to this routine in the addTextbox routine above.

         Dim txtBox as TextBox = CType(sender, TextBox)

          ' Now case out the Tag property and take whatever action you need
         Select Case txtBox.Tag    
              Case 0                       'User edited Textbox #0
                       'Put your code here to edit your long string based on textbox 0's contents.
                       strSearch &= "{" & cboTemplate.SelectedItem & ":[" &
                        lstSelection.Items(i).ToString & "]" & _
                        "=" & txtBox.Text & "}" & "|"

              Case 1                       'User edited Textbox #1

         End Select

    End Sub


- OR - Better yet (at least in terms of human readability)

  Private Sub TextBox_EventHandler(sender As System.Object, e As System.EventArgs)
         ' Cast Sender object to a Textbox.  Sender will be the object that triggered this event.  You know it is
         '  a textbox because you wired the event to this routine in the addTextbox routine above.

         Dim txtBox as TextBox = CType(sender, TextBox)

          ' Now case out the Tag property and take whatever action you need
         Select Case txtBox.Tag    
              Case 0                       'User edited Textbox #0
                       'Put your code here to edit your long string based on textbox 0's contents.
                       strSearch &= String.Format("{{0}:[{1}]={2}}|",  cboTemplate.SelectedItem , lstSelection.Items(txtBox.Tag).ToString, txtBox.Text)

              Case 1                       'User edited Textbox #1

         End Select

    End Sub

This assumes that the lstSelection items were added in the same order as the textboxe's Tag property was assigned.  The idea is that a substring is added to the strSearch variable each time a textbox is edited.  You would need some additional work to validate and prevent duplicates, but if I understand your goal, this should get you on the right track.

Jeff
0
 
LVL 1

Author Comment

by:Trancedified
ID: 10903978
Jeff,

I tried the code but got an error:

An unhandled exception of type 'System.NullReferenceException' occurred in Trial.exe
Additional information: Object reference not set to an instance of an object.

I didn't change anything just copy/paste.

And it points to this line:

            '*****************************
            'Add TextBox to the array
            aTxtBoxes.Add(TextBox)    '<----------------- this one

Chris
0
 
LVL 14

Expert Comment

by:ptakja
ID: 10918674
Sorry,  Change this line:

Private aTxtBoxes as ArrayList


TO

Private aTxtBoxes As New ArrayList()

In my original example above I declared the ArrayList object, but never created it.  That's why you got the NullRef exception because the object didn't exist.

Jeff
0
 
LVL 1

Author Comment

by:Trancedified
ID: 10923344
Jeff,

Ok that fixed it.

Now let's say I have all the necessary textboxes loaded in my form. After typing in some of the boxes, I want to click a button and have maybe
the textbox event handler fire up?
 

Chris
0
 
LVL 1

Author Comment

by:Trancedified
ID: 10923416
Also,

Just wondering if I did this Select..... Case correctly?

        Select Case txtBox.Tag
            Case 0
                For i = 0 To lstSelection.Items.Count - 1
                    strSearch &= "{" & "[" & cboTemplate.SelectedItem & "]" & ":[" & _
                            lstSelection.Items(i).ToString & "]" & _
                            "=" & txtBox.Text & "}"     '<--------- should that be .Tag or .Text?

                Next

Thanks, we're almost done.

Chris
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 14

Expert Comment

by:ptakja
ID: 10928762
Not sure about your question about clicking a button and having the textbox event handler fire up.  Doing that would nullify the event handling for the textboxes that you have set up.  The idea of putting the textboxes into an array is such that when you enter text in a textbox, the Textbox event handler would fire and, using the "sender" object you would be able to determine what textbox the user entered datat into by querying the Tag property.

If you want to do all the string building AFTER the fact, (ie, when you click a button) then you simply can call a routine to loop through the textbox array and pull the data from each textbox object in the array to build your string.  This would be handled in the button click event handler.

There's a couple ways to approach this.

1) Use the common event handler for the textboxes to perform data validation and use a routine as described above to build your string
2) Build the string as you go when the user enters data into each textbox.

Regarding your second question:

       Select Case txtBox.Tag
            Case 0
                For i = 0 To lstSelection.Items.Count - 1
                    strSearch &= "{" & "[" & cboTemplate.SelectedItem & "]" & ":[" & _
                            lstSelection.Items(i).ToString & "]" & _
                            "=" & txtBox.Text & "}"     '<--------- should that be .Tag or .Text?

                Next

That should be .TEXT.  The Tag property is just used to determine which textbox you are dealing with.

Jeff
0
 
LVL 1

Author Comment

by:Trancedified
ID: 10930499
Jeff,

I think we should stick to the event handler that was created for the textboxes. Then find a way to pass the string variable into another routine? While testing to see how the textbox event handler works I put a msgbox at the end of the End Select to check what text is being inputted.

    Private Sub TextBox_EventHandler(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim txtBox As TextBox = CType(sender, TextBox)
        Dim strSearch As String
        Dim i As Integer

        Select Case txtBox.Tag
            Case 0
                For i = 0 To lstSelection.Items.Count - 1
                    strSearch &= "{" & "[" & cboTemplate.SelectedItem & "]" & ":[" & _
                            lstSelection.Items(i) & "]" & _
                            "=" & txtBox.Text & "}"

                Next

            Case 1

                For i = 0 To lstSelection.Items.Count - 1
                    strSearch &= "{" & "[" & cboTemplate.SelectedItem & "]" & ":[" & _
                            lstSelection.Items(i) & "]" & "=" & txtBox.Text & "}" & "|" & "{" & _
                           "[" & cboTemplate.SelectedItem & "]" & _
                            ":[" & lstSelection.Items(i) & "]" & _
                            "=" & txtBox.Text & "}"
                Next

        End Select
        MsgBox(strSearch)
    End Sub

I don't know if I'm doing the Cases right, but I chose two database fields into the listbox, lstSelection called [Last Name] and [First Name].

As I type in:
     345
into either field, in the msgbox I get:

{[Template Name]:[Last Name]=345}|{[Template Name]:[First Name]=345}
(The syntax is right, just 345 is in both areas, I was hoping that if I typed in [First Name], 345 would stick to it's appropriate place, same thing with [Last Name])

Also, when I switch over from textbox Last Name to First Name and start typing, the previous 345 is gone from the two database fields and the msgbox shows me the new text i put in:

{[Template Name]:[Last Name]=g}|{[Template Name]:[First Name]=g}

Any suggestions? Sorry this is the first time I ever used this method.
I appreciate your patience!

Chris

0
 
LVL 14

Expert Comment

by:ptakja
ID: 10930674
Chris,

No problem.  The behavior you are seeing is due to the local variable strSearch.  Try changing the declaration from this:

Dim strSearch As String

TO This:

Static strSearch As String

The Static scope identifier tells the compiler to keep a copy of the variable on the stack.  The other method (with the Dim statement) results in the variable being destroyed when it goes out of scope (ie when the routine exits).

Try this and see if you get the behavior you desire.

Jeff
0
 
LVL 1

Author Comment

by:Trancedified
ID: 10930806
Jeff,

Hmmm unfortunately it's not doing the right behavior using Static. I get the same text:
{[Template Name]:[Last Name]=3}|{[Template Name]:[First Name]=3}

But if I add more text, into either fields it adds more so it'll look like:
{[Template Name]:[Last Name]=3}|{[Template Name]:[First Name]=3}|{[Template Name]:[Last Name]=39}|{[Template Name]:[First Name]=39}

Getting closer...

Chris
0
 
LVL 14

Accepted Solution

by:
ptakja earned 500 total points
ID: 10930926
I think the problem lies with your Case 1 code:

               For i = 0 To lstSelection.Items.Count - 1
                    strSearch &= "{" & "[" & cboTemplate.SelectedItem & "]" & ":[" & _
                            lstSelection.Items(i) & "]" & "=" & txtBox.Text & "}" & "|" & "{" & _
                           "[" & cboTemplate.SelectedItem & "]" & _
                            ":[" & lstSelection.Items(i) & "]" & _
                            "=" & txtBox.Text & "}"
                Next

If you look closely at this code, you are building the string such that it is repeating the data, exactly like you describe.  Try this version instead:

         Case 1
               For i = 0 To lstSelection.Items.Count - 1
                    strSearch &= "{" & "[" & cboTemplate.SelectedItem & "]" & ":[" & _
                            lstSelection.Items(i) & "]" & "=" & txtBox.Text & "}" & "|"
                Next

This only difference between the code for case 0 & case 1 is the addition of the "|" character at the end of the string.

Come to think if it, you may not even need the case.  Can you just do this?
 
     
 Private Sub TextBox_EventHandler(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim txtBox As TextBox = CType(sender, TextBox)
        Static strSearch As String

                For i = 0 To lstSelection.Items.Count - 1
                    strSearch &= "{" & "[" & cboTemplate.SelectedItem & "]" & ":[" & _
                            lstSelection.Items(i) & "]" & _
                            "=" & txtBox.Text & "}|"
                Next

        MsgBox(strSearch)
    End Sub

This would build your string.  The only catch is that you would have a "|" as the last character of your string which you could remove prior to use somewhere.  

Incidentally, if you need this string outside this routine, you will need to move the strSearch variable declaration to have class-level scope.  To do this, declare it like this (put this code under the class declaration in your code):

Private strSearch As String

0
 
LVL 1

Author Comment

by:Trancedified
ID: 10931123
Jeff,

Yeah i tried both ways, 1 with the Select / Case way and 1 without.
By the way this removes the last "|"

strSearch = strSearch.Substring(0, strSearch.Length - 1)

Unfortunately the typed text is still in both areas for [Last Name] and [First Name] just like before.

Chris

0
 
LVL 1

Author Comment

by:Trancedified
ID: 11017070
Jeff,

I couldn't find a solution but thanks for your effort... I went backwards into VB6 and used a control array. This app is simple enough though. I wish it was done in .NET though!


Chris
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Merging PDFs with VB.NET 10 31
Need help with a query 6 55
Setting runtime form location 4 19
Spacing between controls 4 17
Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
Microsoft Reports are based on a report definition, which is an XML file that describes data and layout for the report, with a different extension. You can create a client-side report definition language (*.rdlc) file with Visual Studio, and build g…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now