1

I modified the code present in the accepted answer here to return the first found control of a certain type. But when I try to start traversing from the window itself, VisualTreeHelper.GetChildrenCount returns 0, although there is a grid placed on it. The modifications which I made have no effect on the result.

Here's how I call the method:

DockPanel panel = UIHelper.FindFirstChild<DockPanel>(this);

And here is my XAML code:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="216" Width="267">
    <Grid>
        <DockPanel Height="200" Width="250">
            <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Background="LightBlue">
                <Button Content="01" Margin="1 1 15 1"/>
                <Button Content="02" Margin="1"/>
                <Button Content="03" Margin="1"/>
            </StackPanel>

            <StackPanel Orientation="Horizontal" Height="25" DockPanel.Dock="Bottom" Background="LightBlue">
                <TextBlock VerticalAlignment="Center">Processing...</TextBlock>
                <ProgressBar Value="75" Width="100" Margin="4"/>
            </StackPanel>

            <Grid>
                <TextBlock>Content area</TextBlock>
            </Grid>
        </DockPanel>
    </Grid>    
</Window>
Community
  • 1
  • 1
Kapol
  • 6,383
  • 3
  • 21
  • 46

1 Answers1

5

Because you call it in the constructor visual tree is not ready yet. You should call it in Window.Loaded event instead

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    DockPanel panel = UIHelper.FindFirstChild<DockPanel>(this);
    Console.WriteLine(VisualTreeHelper.GetChildrenCount(panel)); //returns 3
}
dkozl
  • 32,814
  • 8
  • 87
  • 89
  • I stumbled upon another problem. It returns 1 for me, and the type of the control is `System.Windows.Controls.Border`, not a `Grid`... – Kapol May 18 '14 at 17:49
  • what do you mean type is `Border`? You don't have `Border` but it is part of default layout of `Window` for example but you search for `DockPanel` – dkozl May 18 '14 at 17:50
  • In the `FindFirstChild` method after `var child = VisualTreeHelper.GetChild(parent, i);` is executed, `child` is of such type. I'm not saying that the method returns such a control. The `DockPanel` is never found. – Kapol May 18 '14 at 17:51
  • like I said `Border` is part of default layout for `Window` but `FindFirstChild` should go down the visual tree find and return first `DockPanel`. At least version from the question you quoted does that. You can download [Snoop](http://snoopwpf.codeplex.com/) and see how the visual tree looks like – dkozl May 18 '14 at 17:53
  • There must be something wrong with my WPF window then, because the method from mentioned link returns a `Border` as well. – Kapol May 18 '14 at 17:57
  • `Border` is the first child of `Window` and the version of `FindChild` you quoted does `T childType = child as T; if (childType == null) ...` which will be null for `Border` and it call itself recursively looking for children. Maybe you did some changes to original `FindChild` method. Also `FindFirstChild` cannot return `Border` because you assign it to `DockPanel` varaible – dkozl May 18 '14 at 18:02
  • The problem probably lies in the number of children. You stated that the `VisualTreeHelper` finds 3 objects, but when I run the program there is only one object found. The original method has the same effect. I'll create a new project and copy-paste all code there. – Kapol May 18 '14 at 18:27
  • It depends on number of children of what. `Border`, which if first child of `Window`, will have one (or none) as it cannot host more and `DockPanel`, which you search for and assign to `panel` variable, will has 3 children (2 `StackPanel` and `Grid`) and if you will call `VisualTreeHelper.GetChildrenCount(panel)` it will return 3 – dkozl May 18 '14 at 18:44
  • Thank you very much for your feedback, it's all well now. I *did* make a mistake in my code, plus I thought that `Grid` will be a top-level control of the window, but it turns out that the tree looks different than I imagined. – Kapol May 18 '14 at 18:59