WPF uses VisualTreeHelper to traverse a child object or parent object that looks for an object

Source: Internet
Author: User

Brief introduction

This article will be a complete description of my use of visualtreehelper implementation of the whole process of the function, want to see directly the function of the realization of friends can jump to the function implementation part.
or download the source code directly on GitHub.
  
We often encounter this situation in WPF: When we try to find the child or parent control of a control on a form or page, we can only find its first level of logical child or parent object. When we want to go deeper, there is no way out.
Even in our custom DataTemplate controls, we have no way to access them. For example, in a ListView custom control, we have no way to get control of the specified position. Examples can be found in my blog post: Controls in Custom DataTemplate in WPF, and the mechanism of loading in window_loaded events.
This article explores the solution.

VisualTreeHelper

In the VisualTreeHelper class, Microsoft provides utility methods for performing common tasks involving nodes in a visual tree, and some methods in the VisualTreeHelper class can accept DependencyObject that represent any type of visual object Value.
Here we are going to use two methods: Visualtreehelper.getchild () and Visualtreehelper.getparent ().

Using VisualTreeHelper to simulate a scene build

Create a new WPF project, named Visualtreehelperdemo.
Suppose we have a main form as shown below, the content container of a form is a grid control name= "Topgrid", which contains up to two child grids, each of which contains a button in each child grid.
  
The MainWindow.xaml code is as follows:

<window x:class="Visualtreehelper.mainwindow"xmlns="http// Schemas.microsoft.com/winfx/2006/xaml/presentation "xmlns:x=" http://schemas.microsoft.com/ Winfx/2006/xaml "Title=" MainWindow " Height=" = " Width= "525">                            <Grid Name="Topgrid">        <grid.rowdefinitions>            <rowdefinition></rowdefinition>            <rowdefinition></rowdefinition>        </grid.rowdefinitions>        <Grid >            <button Content="Button1" Name="Btn_one"  VerticalAlignment="center" horizontalalignment="center">            </Button>        </Grid>        <Gridgrid.row="1">              <button Content="Button2" Name="Btn_two"  VerticalAlignment="center" horizontalalignment="center">            </Button>        </Grid>    </Grid></Window>
Traverse looking for child objects

Now let's look for Topgrid All button child objects and output their names.
Open the MainWindow.xaml.cs file and add the following code to find the child objects:

//   <summary> ///   use VisualTreeHelper to find child objects of an object//   </summary> ///   <typeparam name= "T" ></typeparam> //   <param name= "obj" ></param> ///   <returns></returns> List<t> findvisualchild<t> (DependencyObject obj)wheret:dependencyobject{Try{List<t> TList =Newlist<t> {}; for(inti =0; I < Visualtreehelper.getchildrencount (obj); i++) {DependencyObject child = Visualtreehelper.getchild (obj, i);if(Child! =NULL&& Child isT) {Tlist.add ((T) child); }Else{list<t> Childofchildren = findvisualchild<t> (child);if(Childofchildren! =NULL) {Tlist.addrange (Childofchildren); }            }        }returnTList; }Catch(Exception ee) {MessageBox.Show (EE. Message);return NULL; }}

In the Btn_one_click event, write the following code:

//   <summary> ///   Form Load Events//   </summary> ///   <param name= "sender" ></param> ///   <param name= "E" ></param> Private void Btn_one_click(Objectsender, RoutedEventArgs e) {stringBtnname =""; list<button> btnlist = findvisualchild<button> (Topgrid);foreach(Button IteminchBtnlist) {Btnname + =string. IsNullOrEmpty (btnname)? Item. Name.tostring ():","+ Item.    Name.tostring (); } Show (string. Format (TopGrid.Name.ToString () +"Total {0} buttons with name {1}", Btnlist.count, Btnname));}

Run the program, click Button1, and the results are as follows:
  
  
  
The result shows that the traversal was successful.
  

Traverse looking for parent object

Now let's traverse Button2 's parent object, get information about all of its parent objects, and show it.
Open the MainWindow.xaml.cs file and add the code that looks for the parent object as follows:

//   <summary> ///   use VisualTreeHelper to find the parent object of the specified dependent object//   </summary> ///   <typeparam name= "T" ></typeparam> //   <param name= "obj" ></param> ///   <returns></returns>  Public StaticList<t> findvisualparent<t> (DependencyObject obj)wheret:dependencyobject{Try{List<t> TList =Newlist<t> {}; DependencyObject parent = visualtreehelper.getparent (obj);if(Parent! =NULL&& Parent isT) {Tlist.add ((T) parent); list<t> parentofparent = findvisualparent<t> (parent);if(Parentofparent! =NULL) {Tlist.addrange (parentofparent); }        }Else{        }returnTList; }Catch(Exception ee) {MessageBox.Show (EE. Message);return NULL; }}

Add the following code in the Btn_two_click:

//   <summary> ///   Traverse Button2 Parent Object Information//   </summary> ///   <param name= "sender" ></param> ///   <param name= "E" ></param> Private void Btn_two_click(Objectsender, RoutedEventArgs e) {stringParentName =""; list<grid> gridlist = findvisualparent<grid> (btn_two);foreach(Grid IteminchGridlist) {ParentName + =string. IsNullOrEmpty (parentname)? Item. Name.tostring ():","+ Item.    Name.tostring (); } MessageBox.Show (string. Format (btn_Two.Name.ToString () +"A total of {0} logical parents with names of {1}", Gridlist.count, ParentName));}

Run the program, click Button2, the effect is as follows:

The result shows that the traversal was successful.

Summarize

In this way we can get the control object we want and manipulate it, including the controls in the custom DataTemplate.

WPF uses VisualTreeHelper to traverse a child object or parent object that looks for an object

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.