Click here to Skip to main content
15,890,438 members
Please Sign up or sign in to vote.
1.44/5 (2 votes)
Hello, I have a problem. I need to return data from SQL into a Window to fill in textboxes. If a textbox is empty post return, then turn the background color == red.

I got it to work using the code below:

C#
private void PlayingWithColors()
{
    foreach (var tb in FindVisualChildren<TextBox>(this).Where(tb => tb.Text == String.Empty))
    {
        tb.Background = Brushes.Red;
    }
}

public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
    if (depObj == null) yield break;
    for (var i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
    {
        var child = VisualTreeHelper.GetChild(depObj, i);
        var children = child as T;
        if (children != null)
        {
            yield return children;
        }

        foreach (var childOfChild in FindVisualChildren<T>(child))
        {
            yield return childOfChild;
        }
    }
}


The problem is the end users. They now want a smaller window and tabs. So as soon as I added the tabcontrol, I lost the functionality. What am I doing wrong or what can I do differently to read through the tabs for all textboxes?

Example XAML:

C#
<TabItem Header="Vitals">
                <GroupBox Header="Vital Signs" FontWeight="Bold" BorderBrush="Black" BorderThickness="1"
                          Margin="10">
                    <StackPanel Margin="10" HorizontalAlignment="Left" Width="782">
                        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Width="171"
                                   Margin="1,1,1,0"
                                   UseLayoutRounding="True" Height="30">
                            <Label Content="HR:                " FontWeight="Normal"
                                   HorizontalAlignment="Left" VerticalContentAlignment="Center"
                                   Height="27" />
                            <TextBox x:Name="TbHr" TextWrapping="Wrap" Text="" HorizontalAlignment="Center"
                                     Width="75" VerticalContentAlignment="Center"
                                     HorizontalContentAlignment="Left" Height="27" />
                        </TextBlock>
                        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Width="171"
                                   Margin="1,1,1,0"
                                   UseLayoutRounding="True" Height="30">
                            <Label Content="RR:                 " FontWeight="Normal"
                                   HorizontalAlignment="Left" VerticalContentAlignment="Center"
                                   Height="27" />
                            <TextBox x:Name="TbRr" TextWrapping="Wrap" Text="" HorizontalAlignment="Center"
                                     Width="75" VerticalContentAlignment="Center"
                                     HorizontalContentAlignment="Left" Height="27" />
                        </TextBlock>
                        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Width="171"
                                   Margin="1,1,1,0"
                                   UseLayoutRounding="True" Height="30">
                            <Label Content="BP:                 " FontWeight="Normal"
                                   HorizontalAlignment="Left" VerticalContentAlignment="Center"
                                   Height="27" />
                            <TextBox x:Name="TbBp" TextWrapping="Wrap" Text="" HorizontalAlignment="Center"
                                     Width="75" VerticalContentAlignment="Center"
                                     HorizontalContentAlignment="Left" Height="27" />
                        </TextBlock>
                        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Width="171"
                                   Margin="1,1,1,0"
                                   UseLayoutRounding="True" Height="30">
                            <Label Content="Weight:          " FontWeight="Normal"
                                   HorizontalAlignment="Left" VerticalContentAlignment="Center"
                                   Height="27" />
                            <TextBox x:Name="TbWgt" TextWrapping="Wrap" Text=""
                                     HorizontalAlignment="Center"
                                     Width="75" VerticalContentAlignment="Center"
                                     HorizontalContentAlignment="Left" Height="27" />
                        </TextBlock>
                        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Width="171"
                                   Margin="1,1,1,0"
                                   UseLayoutRounding="True" Height="30">
                            <Label Content="Weight Type: " FontWeight="Normal"
                                   HorizontalAlignment="Left" VerticalContentAlignment="Center"
                                   Height="27" ToolTip="lb or kg" />
                            <TextBox x:Name="TbWgtType" TextWrapping="Wrap" Text=""
                                     HorizontalAlignment="Center"
                                     Width="75" VerticalContentAlignment="Center"
                                     HorizontalContentAlignment="Left" Height="27" />
                        </TextBlock>
                        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Width="181"
                                   Margin="1,1,1,0"
                                   UseLayoutRounding="True" Height="30">
                            <Label Content="Vital Date:      " FontWeight="Normal"
                                   HorizontalAlignment="Left" VerticalContentAlignment="Center"
                                   Height="27" ToolTip="lb or kg" />
                            <TextBox x:Name="TbVitalDate" TextWrapping="Wrap" Text=""
                                     HorizontalAlignment="Center"
                                     Width="87" VerticalContentAlignment="Center"
                                     HorizontalContentAlignment="Left" Height="27" />
                        </TextBlock>
                    </StackPanel>
                </GroupBox>
            </TabItem>
Posted
Updated 6-Nov-17 8:06am
v2

Issue is with iterating over Visual Tree to find control. If you debug your application you can see that TextBox Control that is present different tabitem than current is not visible and hence not shown in Visual Tree.

Just replace FindVisualChildren method with

C#
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject obj) where T : DependencyObject
       {
           if (obj != null)
           {
               if (obj is T)
                   yield return obj as T;

               foreach (DependencyObject child in LogicalTreeHelper.GetChildren(obj).OfType<DependencyObject>())
                   foreach (T c in FindVisualChildren<T>(child))
                       yield return c;
           }
       }



Hope this will solve your problem.
 
Share this answer
 
Comments
Derek Kennard 19-Jul-15 16:11pm    
Man, I have so much more to learn. Thank you for the information. I worked like a champ!
Mahindra Shambharkar 20-Jul-15 3:52am    
Goodness it worked, I am still learning WPF :)
Member 14046590 4-Mar-19 7:48am    
The best (and most compact) answer I found about this issue. Works perfectly with TabControl
Based on the above solution, I tweaked the code so you can pas in a WPF window with tab controls or other containers, and it will loop through all the textbox controls. The TB controls are added to a visual items list and with the returned list you can do whatever you like.

Remove the where clause to remove the restriction for only empty textboxes. Don't forget to close the bracket after (parent) )

Remove this ==> .Where(tb => tb.Text == String.Empty))

<pre>public class cEnumControls
    {
        public static List<Visual> EnumVisual(UIElement Parent, List<Visual> collection)
        {
            foreach (var tb in FindVisualChildren<TextBox>(Parent).Where(tb => tb.Text == String.Empty))
            {
                collection.Add((Visual)tb);
                //tb.Background = Brushes.Red;
            }
            return collection;
        }


        public static IEnumerable<T> FindVisualChildren<T>(DependencyObject obj) where T : DependencyObject
        {
            if (obj != null)
            {
                if (obj is T)
                    yield return obj as T;

                foreach (DependencyObject child in LogicalTreeHelper.GetChildren(obj).OfType<DependencyObject>())
                    foreach (T c in FindVisualChildren<T>(child))
                        yield return c;
            }
        }
    }
 
Share this answer
 
v2
Comments
Richard Deeming 6-Nov-17 15:50pm    
This question was solved over TWO YEARS ago. And your solution doesn't really add anything to the accepted solution - it even copies the FindVisualChildren method verbatim!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900