0

how can I get the first "user control" of a subset of a parent (window or page) within the same control.

For example, I want to find the first custom text box from the opened window and I intend to do this within the code behind of custom text box.

enter image description here

Rufus L
  • 36,127
  • 5
  • 30
  • 43

2 Answers2

0

You can use the VisualTreeHelper.GetParent helper:
So inside you custom control:

var parent = VisualTreeHelper.GetParent(this);

Then you can check the type of that:

UIElement neighbor;
if (parent is Panel p)
    neighbor = p.Children.First();
else if (parent is ItemsControl i)
    neighbor = i.Items.First() as UIElement;

NOTE: Depending on your visual tree you may need to go up multiple levels using VisualTreeHelper.GetParent on the parent again:

UIElement parent = this;
while (parent != null && !(parent is Panel))
    parent = VisualTreeHelper.GetParent(parent);
return (parent as Panel)?.Children.First();
Christoph Fink
  • 22,727
  • 9
  • 68
  • 113
0

Several possibilities:

  1. Label the 1st inserted into Xaml with a (x:)Name="yourFirstElement" - no need to search, just access it from its bretheren by the name
  2. Use the Page.Content to get it, if you know which layout is in it you can go from there (f.e. DockPanel.Children or DockPanel.GetVisualChild(int) in combination with searching all VisualChildren and testing for your type.
  3. VisualTreeHelper.GetChild(parent,index) - caveat might be a "pure" visual not a decendend of FrameworkElement. Example of that here: How to get children of a WPF container by type?
  4. LogicalTreeHelper.GetChildren(myWindow) , Example of that here: Finding ALL child controls WPF for (combines Logical- and VisualTreeHelper to overcome the limitations of LogicalTreeHelper regarding not finding pure visuals with keeping speed of "logical" search.

If you are in a CustomControl this derives somehow from FrameworkElement which has a Parent property. Use that, if it is your Page you are an only-child (aka Content of the Page). If it is a Layout-Container like Grid,StackPanel, DockPanel etc they all derive from Panel which has a Children property which you use with .First() to get the first Child.

If you want the first in Tab order you would need to iterate all the Children and find the one with the lowest TabIndex (UserControl -> ContentControl -> Control which has TabIndex) value - f.e. with Children.OrderBy(ele => ele.TabIndex).First()

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69