WPF利用VisualTreeHelper遍历寻找对象的指定子级对象或者指定父级对象

2021/7/24 6:05:08

本文主要是介绍WPF利用VisualTreeHelper遍历寻找对象的指定子级对象或者指定父级对象,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

 

转载 https://www.cnblogs.com/dotnetHui/p/8342398.html

 

 

微软在VisualTreeHelper类中,提供了一些实用工具方法,用于执行涉及可视化树中的节点的常规任务,VisualTreeHelper 类中的一些方法可以接受表示任意一种可视对象类型的 DependencyObject 值。 
  这里我们将要用到两个方法分别是:VisualTreeHelper.GetChild()和VisualTreeHelper.GetParent()。

使用VisualTreeHelper

模拟场景搭建

  新建一个WPF工程,命名为VisualTreeHelperDemo。 
  假设我们有如下如所示的一个主窗体,窗体的内容容器为一个name=”TopGrid”的Grid控件,它包含了上下两个子级Grid,每个子级Grid中各自包含了一个Button。 
  这里写图片描述 
  MainWindow.xaml代码如下:  

<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="350" 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>
        <Grid  Grid.Row="1">
            <Button Content="Button2" Name="btn_Two" VerticalAlignment="Center" HorizontalAlignment="Center">
            </Button>
        </Grid>
    </Grid>
</Window>

  MainWindow.xaml代码如下:

<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="350" 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>
        <Grid  Grid.Row="1">
            <Button Content="Button2" Name="btn_Two" VerticalAlignment="Center" HorizontalAlignment="Center">
            </Button>
        </Grid>
    </Grid>
</Window>

  

遍历寻找子级对象

  现在我们来寻找TopGrid所有Button子级对象,并输出它们的名称。 
  打开MainWindow.xaml.cs文件,添加寻找子级对象的代码如下:

/// <summary>
/// 利用visualtreehelper寻找对象的子级对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
List<T> FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
{
    try
    {
        List<T> TList = new List<T> { };
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(obj, i);
            if (child != null && child is T)
            {
                TList.Add((T)child);
                List<T> childOfChildren = FindVisualChild<T>(child);
                if (childOfChildren != null)
                {
                    TList.AddRange(childOfChildren);
                }
            }
            else
            {
                List<T> childOfChildren = FindVisualChild<T>(child);
                if (childOfChildren != null)
                {
                    TList.AddRange(childOfChildren);
                }
            }
        }
        return TList;
    }
    catch (Exception ee)
    {
        MessageBox.Show(ee.Message);
        return null;
    }
}

  在btn_One_Click事件里面书写代码如下:

/// <summary>
/// 窗体加载事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_One_Click(object sender, RoutedEventArgs e)
{
    string btnName = "";
    List<Button> btnList = FindVisualChild<Button>(TopGrid);
    foreach (Button item in btnList)
    {
        btnName += string.IsNullOrEmpty(btnName) ? item.Name.ToString() : "," + item.Name.ToString();
    }
    Show(string.Format(TopGrid.Name.ToString()+"共有{0}个Button,名称分别为{1}", btnList.Count, btnName));
}

  

运行程序,点击Button1,结果如下图: 

 
  这里写图片描述

遍历寻找父级对象

  现在我们来遍历Button2的父级对象,获得其所有父级对象的信息,并且展示。 
  打开MainWindow.xaml.cs文件,添加寻找父级对象的代码如下:

 
/// <summary>
/// 利用VisualTreeHelper寻找指定依赖对象的父级对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static List<T> FindVisualParent<T>(DependencyObject obj) where T : DependencyObject
{
    try
    {
        List<T> TList = new List<T> { };
        DependencyObject parent = VisualTreeHelper.GetParent(obj);
        if (parent != null && parent is T)
        {
            TList.Add((T)parent);
            List<T> parentOfParent = FindVisualParent<T>(parent);
            if (parentOfParent !=null)
            {
                TList.AddRange(parentOfParent);
            }
        }
        else if ( parent != null )
        {
             List<T> parentOfParent = FindVisualParent<T>(parent);
             if (parentOfParent != null)
             {
                 TList.AddRange(parentOfParent);
             }
        }
        return TList;
    }
    catch (Exception ee)
    {
        MessageBox.Show(ee.Message);
        return null;
    }
}

  在btn_Two_Click中添加代码如下:

/// <summary>
/// 遍历Button2父级对象信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Two_Click(object sender, RoutedEventArgs e)
{
    string parentName = "";
    List<Grid> gridList = FindVisualParent<Grid>(btn_Two);
    foreach (Grid item in gridList)
    {
        parentName += string.IsNullOrEmpty(parentName) ? item.Name.ToString() : "," + item.Name.ToString();
    }
    MessageBox.Show(string.Format(btn_Two.Name.ToString() + "共有{0}个逻辑父级,名称分别为{1}", gridList.Count, parentName));
}

  

运行程序,点击Button2,效果如下: 
这里写图片描述 
  结果表明遍历成功。

总结



这篇关于WPF利用VisualTreeHelper遍历寻找对象的指定子级对象或者指定父级对象的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程