Question

I have a list box that contains items that are represented by a single textbox.

When the user clicks a button, I want to iterate thru all these text boxes and check if their binding expressions are clean of errors; Should be something like:

    Dim errCount = 0
    For Each item In MyListBox.ListBoxItems 'There is no such thing ListBoxItems which is actually what I am looking for.
        Dim tb As TextBox = item '.........Dig in item to extract the textbox from the visual tree.
        errCount += tb.GetBindingExpression(TextBox.TextProperty).HasError
    Next
    If errCount Then
        'Errors found!
    End If

Any discussion would be really appreciated. Thanks.

Was it helpful?

Solution

There may be an easier way to do this, but here is one option that will work:

1) Iterate through the list of items.

Because you are using items source, ListBox.Items will refer to the data items in the ItemsSource.

for (int i = 0; i < ListBox.Items.Count; i++)
{
    // do work as follows below...
}

2) Get the containers for these items.

DependencyObject obj = ListBox.ItemContainerGenerator.ContainerFromIndex(i);

3) Use VisualTreeHelper to search for a TextBox child of the container visual.

TextBox box = FindVisualChild<TextBox>(obj);

Use this function to search for a visual child of the correct type:

public static childItem FindVisualChild<childItem>(DependencyObject obj)
    where childItem : DependencyObject
{
    // Search immediate children
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(obj, i);

        if (child is childItem)
            return (childItem)child;

        else
        {
            childItem childOfChild = FindVisualChild<childItem>(child);

            if (childOfChild != null)
                return childOfChild;
        }
    }

    return null;
}

4) Finally, examine the binding on the TextBox.

All put together, something like this:

private bool ValidateList(ListBox lb)
{
    for (int i = 0; i < lb.Items.Count; i++)
    {
        DependencyObject obj = lb.ItemContainerGenerator.ContainerFromIndex(i);
        TextBox box = FindVisualChild<TextBox>(obj);
        if (!TestBinding(box))
            return false;
    }

    return true;
}

OTHER TIPS

Translation of previous post to VB:

1)

For i As Integer = 0 To ListBox.Items.Count - 1 
    ' do work as follows below... 
Next

2)

Dim obj As DependencyObject = ListBox.ItemContainerGenerator.ContainerFromIndex(i)

3)

Dim box As TextBox = FindVisualChild(Of TextBox)(obj)
'************************
Public Shared Function FindVisualChild(Of ChildItem As DependencyObject)(ByVal obj As DependencyObject) As ChildItem
    ' Search immediate children 
    For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(obj) - 1
        Dim child As DependencyObject = VisualTreeHelper.GetChild(obj, i)
        If TypeOf child Is ChildItem Then
            Return child
        Else
            Dim childOfChild As ChildItem = FindVisualChild(Of ChildItem)(child)
            If childOfChild IsNot Nothing Then Return childOfChild
        End If
    Next
    Return Nothing
End Function

4)

Private Function ValidateList(ByVal lb As ListBox) As Boolean 
For i As Integer = 0 To lb.Items.Count - 1 
    Dim obj As DependencyObject = lb.ItemContainerGenerator.ContainerFromIndex(i) 
    Dim box As TextBox = FindVisualChild(Of TextBox)(obj) 
    If Not TestBinding(box) Then 
        Return False 
    End If 
Next 
Return True 

End Function

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