How to loop through nest controls in ListBoxItem to find a TextBox?

hurdy

Member
Joined
Mar 24, 2011
Messages
5
Programming Experience
Beginner
Hi everyone,

Firstly, thank you for taking the time out to read this post.

I'm having trouble trying to loop through a WPF ListBox control to find a nested TextBox in VB.net 3.5.

Here is my UI structure:

TabControl > TabItem > UserControl > Grid > ListBox > ListBoxItem > Grid > TextBox

I have a page that Contains a TabControl. When the TabControl loads, I loop through each TabItem to dynamically add a UserControl which contains a grid, where the first grid row contains a ListBox. In each ListBox I dynamically add 8 ListItems, where each item is DataTemplate that contains another Grid that houses an Image, TextBox and Button.

I need to loop through all of the items to find the textbox nested in each ListBoxItem. I've managed to drill down the the ListBoxItem level but I don't know how to dig further down to find the TextBox.

Here is my VB code so far:



VB.NET:
[SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'Loop through TabItems in TabControl[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]For[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] tabItems [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Integer[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = 0 [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]To[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] tabInspection.Items.Count - 1[/SIZE]
[SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]   'Create object of the current TabItem[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]    Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] tabItem [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] TabItem = tabInspection.Items(tabItems)[/SIZE]
[SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]   'Continue if TabItem Header is not Save and Exit[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]   If[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] tabItem.Header <> [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"Save and Exit"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]       'Find ListBox that is nested in UserControl > Grid[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]       For[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Each[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] ctrl [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] Control [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]In[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] tabItem.Content.Content.Children[/SIZE]
[SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]            'Check if control found is a ListBox[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]            If[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] ctrl.GetType().FullName = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]GetType[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2](ListBox).FullName [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Then[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]                   'Create Control object of the ListBox[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]                   Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] lstBox [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] ListBox = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]CType[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2](ctrl, ListBox)[/SIZE]
[SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]                   'Loop Through ListBox items[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]                    For[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Each[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] item [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]In[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] lstBox.Items[/SIZE]
[SIZE=2]                          MessageBox.Show(item.ToString, [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"List Box Item"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]                       ' *** NEED TO FIND TEXTBOX CONTROL NESTED IN A LISTBOX ITEM [/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]                  Next[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]            End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]        Next[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]   End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE]
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Next[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]
[/COLOR][/SIZE]

Any advice is greatly appreciated.

Thank you for your time,

Rob
 
You can try something like if typeof item is textbox then (you are on a textbox item in the list box loop). I didn't think the listbox had the functionality to store controls in it, but that may have changed from .NET 2.0 to 3.5.
 
Each ListBox item is made up from a data template, thus allowing me to create any structure I wish within the listbox items. You can put anything you like in there such as images, comobo box's and videos etc etc, if you so wish to. Usually you bind the listbox items to something like an ObservableCollection(of ), where two way syncing. So if a Textbox was edited in a ListBox item, it would auctomatically update the Collection List. Sadly I'm not binding to a datasource in the first place, thus I need to create a List based on the ListBox items data.

I'm pretty sure there must be a way to loop through each control in a ListBox item. The problem is is that my controls are nested inside a Grid, which is inside each of the ListBox items.

My nested loops to access the TextBox's that I need inside each ListBox item needs to be something like this:

TabControl > TabItems > UserControl > Grid > ListBox > StackPanel > ListBoxItem > Grid > TextBox

As you can see there's a lot of nesting going on here.
 
Then it would be the controls collection of the object to loop through any containers' controls. And use the typeof method to see if it the typeof control you want, but what i said above didn't help?

You can try something like if typeof item is textbox
 
Thank for the reply.

I've managed to crack it. I've used the VisualTreeHelper function to drill down through the different layers.

Here's my code:

VB.NET:
[SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] btnSave_Click([/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] System.Object, [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] System.Windows.RoutedEventArgs) [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] btnSave.Click
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'*** FIND DATA IN TEXTBOX's FROM EACH OF THE LISTBOX's IN EACH TABITEM
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'Loop through TabItems in TabControl
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]For[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] tabItems [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Integer[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = 0 [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]To[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] tabInspection.Items.Count - 1
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'Create object of the current TabItem
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] tabItem [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] TabItem = tabInspection.Items(tabItems)
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'Continue if TabItem Header is not Save and Exit
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] tabItem.Header <> [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"Save and Exit"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Then
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'Find ListBox that is nested in TabItem > UserControl > Grid > 
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]For[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Each[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] ctrl [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] Control [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]In[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] tabItem.Content.Content.Children
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'Find TexTBox in each ListBoxItem
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]ProcessElement(ctrl, tabItem)
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Next
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Next
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff][/COLOR][/SIZE][/COLOR][/SIZE] 
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff][/COLOR][/SIZE][/COLOR][/SIZE] 
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] ProcessElement([/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] element [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] DependencyObject, [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] listTabItem [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] TabItem)
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'Check if element is a TextBox
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] element.GetType().FullName = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]GetType[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2](TextBox).FullName [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Then
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'Create TextBox object of the found textbox
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Dim[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] tbx [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] TextBox = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]CType[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2](element, TextBox)
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]'Check if TextBox has text
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] tbx.Text <> [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]""[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Then
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]MessageBox.Show([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"Room: "[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] & listTabItem.Header.ToString & vbCr & [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"Text: "[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] & tbx.Text.ToString & vbCr & _
[/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"Tag: "[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] & listTabItem.Tag.ToString, [/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"TextBox"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2])
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]If
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]' Check if this element contains other elements.
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]For[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] i [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Integer[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] = 0 [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]To[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] VisualTreeHelper.GetChildrenCount(element) - 1
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]' Process each contained element recursively.
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]ProcessElement(VisualTreeHelper.GetChild(element, i), listTabItem)
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Next
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]Sub
[/COLOR][/SIZE][/COLOR][/SIZE][/COLOR][/SIZE][/COLOR][/SIZE]

Thanks for your help. It's greatly appreciated.

Rob

Sorry about the formatting of the code. It doesn't seem to have copied across properly.
 
Wow .NET 3.5 has some really cool stuff I've been stuck on 2.0 for too long. Using my 2010 visual studio I created the following code:

VB.NET:
Public Class Form1

    Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged

        For Each obj As Object In ListBox1.Items
            If TypeOf obj Is TextBox Then
                MsgBox("TEXT BOX")
            End If
            If TypeOf obj Is Button Then
                MsgBox("BUTTON")
            End If
            If TypeOf obj Is Control Then
                MsgBox("ALL 3 ARE CONTROLS")
            End If
        Next
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ListBox1.Items.Add(New TextBox)
        ListBox1.Items.Add(New Button)
        ListBox1.Items.Add(New Control)
    End Sub
End Class

When you select an item in this form you should get five message boxes.
 
ss7thirty, this thread is about WPF, not winforms.
 
Back
Top