1

I have a user control with a DependencyProperty that takes a UIElement. So far, so good, the problem is I cannot find the element's children.

I think the problem is my lack of knowledge, could anyone tell me what the problem is and a possible solution?

I have made a small test-program like this

Usercontrol codebehind:

public UIElement TestSendUiElement
{
   get { return (StackPanel)GetValue(TestSendUiElementProperty); }
   set { SetValue(TestSendUiElementProperty, value); }
}

public static readonly DependencyProperty TestSendUiElementProperty =
 DependencyProperty.Register("TestSendUiElement", typeof(StackPanel), typeof(Test), new FrameworkPropertyMetadata(TestSendUiElementPropertyChanged));

private static void TestSendUiElementPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
   Console.WriteLine(VisualTreeHelper.GetChildrenCount((UIElement)e.NewValue));
}

xaml using the usercontrol:

<my:Test >
 <my:Test.TestSendUiElement>
  <StackPanel Orientation="Horizontal" Margin="0,2">
   <TextBox Height="23" Width="50" Margin="0,0,5,0" />
   <TextBox Height="23" Width="125" />
  </StackPanel>
 </my:Test.TestSendUiElement>
</my:Test>

Output is 0 children. Shouldn't it be 2?

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Cinaird
  • 785
  • 4
  • 13
  • 33

2 Answers2

0

I think it doesn't work because whatever you assign to the TestSendUiElement DependencyProperty, it won't be part of the VisualTree. So VisualTreeHelper.GetChildrenCount(...) will not work.

As a direct replacement, LogicalTreeHelper should do the trick.

And if you know the type of the object or can , then it's even better to use exposed properties like ItemsControl.Items, ContentControl.Content and etc., with the exception of classes inheriting from Panel (they're LogicalChildren property is internal).

If you are lazy you could also do the following (untested code):

<my:Test.TestSendUiElement>
  <ItemsControl Margin="0,2">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <TextBox Height="23" Width="50" Margin="0,0,5,0" />
    <TextBox Height="23" Width="125" />
    <ItemsControl>
</my:Test.TestSendUiElement>

Then you change the type of the DP property to ItemsControl, and now you can access the children via this.TestSendUIElement.Items. An ItemsControl is probably not as lightweight as a panel, but using the LogicalTreeHelper probably wouldn't be optimal either. Depends on the scenario.

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Alex Maker
  • 1,529
  • 2
  • 19
  • 27
  • LogicalTreeHelper seams to be the best way in my case. But when i tire this I only get this output: System.Windows.LogicalTreeHelper+EnumeratorWrapper. So i don't get any children i kan loop through. Should I get children? – Cinaird Oct 20 '10 at 14:02
0

The content is no Initialized so count the object on initialization

protected override void OnInitialized(EventArgs e)
{
   base.OnInitialized(e);
   Console.WriteLine(VisualTreeHelper.GetChildrenCount((UIElement)e.NewValue));
}

And you will get count 2

Cinaird
  • 785
  • 4
  • 13
  • 33