WPF 利用视觉树获取指定名称对象、指定类型对象、以及判断是否有验证错误

1.利用视觉树获取指定名称对象

cs 复制代码
/// <summary>
/// Finds a Child of a given item in the visual tree.
/// </summary>
/// <param name="parent">A direct parent of the queried item.</param>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="childName">x:Name or Name of child. </param>
/// <returns>The first parent item that matches the submitted type parameter.
/// If not matching item can be found,
/// a null parent is being returned.</returns>
public static T GetChildWithName<T>(this DependencyObject parent, string childName)
   where T : DependencyObject
{
    // Confirm parent and childName are valid.
    if (parent == null) return null;

    T foundChild = null;

    int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < childrenCount; i++)
    {
        var child = VisualTreeHelper.GetChild(parent, i);
        // If the child is not of the request child type child
        T childType = child as T;
        if (childType == null)
        {
            // recursively drill down the tree
            foundChild = GetChildWithName<T>(child, childName);

            // If the child is found, break so we do not overwrite the found child.
            if (foundChild != null) break;
        }
        else if (!string.IsNullOrEmpty(childName))
        {
            var frameworkElement = child as FrameworkElement;
            // If the child's name is set for search
            if (frameworkElement != null && frameworkElement.Name == childName)
            {
                // if the child's name is of the request name
                foundChild = (T)child;
                break;
            }
        }
        else
        {
            // child element found.
            foundChild = (T)child;
            break;
        }
    }

    return foundChild;
}

2.返回指定类型的子对象

比如:在一个Grid内部有很多TextBox/ComboBox ,需要获取这个控件对象。

var children=Grid.GetChildren(new List<Type>(){ typeof(TextBox),typeof(ComboBox)});

cs 复制代码
/// <summary>
/// 返回指定类型的子对象
/// </summary>
/// <param name="p_element"></param>
/// <param name="includeTypes"></param>
/// <returns></returns>
public static IEnumerable<UIElement> GetChildren(this DependencyObject p_element, List<Type> includeTypes)
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(p_element); i++)
    {
        var child = VisualTreeHelper.GetChild(p_element, i) as UIElement;
        if (child == null)
        {
            continue;
        }

        Type type = child.GetType();

        if (includeTypes.Contains(type))
        {
            yield return child;
        }
        else
        {
            foreach (var c in child.GetChildren(includeTypes))
            {
                yield return c;
            }
        }
    }
}

3.获取UI对象(UserControl)内部是否存在验证错误

string errorMsg=string.Empty;

if(UserControl.GetChildrenValidationHasError<TextBox>(ref errorMsg))

{

//UserControl 内部的TextBox 有验证错误

MessageBox.Show(errorMsg);//提示错误消息

}

cs 复制代码
/// <summary>
/// 获取当前DependencyObject(含特定类型子对象)是否存在Validation错误
/// </summary>
/// <param name="p_element"></param>
/// <param name="errorMsg"></param>
/// <returns></returns>
public static bool GetChildrenValidationHasError<T>(this DependencyObject p_element, ref string errorMsg) where T : UIElement
{
    var children = GetChildren<T>(p_element);
    foreach (var child in children)
    {
        if (CheckDependencyObjectHasError(child, ref errorMsg))
        {
            return true;
        }
    }
    return false;
}

/// <summary>
/// 获取当前DependencyObject(含所有UI子对象)是否存在Validation错误
/// </summary>
/// <param name="p_element"></param>
/// <param name="errorMsg"></param>
/// <returns></returns>
public static bool GetChildrenValidationHasError(this DependencyObject p_element, List<Type> includeTypes, ref string errorMsg)
{
    var children = GetChildren(p_element, includeTypes);
    foreach (var child in children)
    {
        if (CheckDependencyObjectHasError(child, ref errorMsg))
        {
            return true;
        }
    }
    return false;
}

/// <summary>
/// 获取当前DependencyObject是否存在Validation错误
/// </summary>
/// <param name="child"></param>
/// <param name="errorMsg"></param>
/// <returns></returns>
public static bool CheckDependencyObjectHasError(this DependencyObject child, ref string errorMsg)
{
    if (child != null && Validation.GetHasError(child))
    {
        var errors = Validation.GetErrors(child);
        if (errors != null)
        {
            errorMsg = string.Join("\n\r", errors.Select(m => m.ErrorContent).ToArray());
        }
        return true;
    }
    return false;
}
相关推荐
Chris _data3 天前
WPF 学习第三天 — Modbus RTU 串口通信
hadoop·学习·wpf
布吉岛的石头3 天前
Java 程序员第 43 阶段05:微服务整合大模型,跨服务调用架构设计实战,Seata分布式事务实战
wpf
步步为营DotNet3 天前
基于.NET Aspire 实现云原生应用的高效监控与可观测性
云原生·.net·wpf
芒鸽4 天前
HarmonyOS 分布式开发实战:设备协同、数据共享与跨设备迁移
分布式·wpf·harmonyos
Volunteer Technology4 天前
Flink状态管理与容错(二)
大数据·flink·wpf
happyprince5 天前
07_verl-Trainer模块详解
人工智能·架构·wpf·强化学习
bugcome_com5 天前
WPF + Prism 技术指南与实战项目(二、模板搭建)
wpf
小满Autumn5 天前
log4net 日志框架 — 从配置到实战速查手册
笔记·c#·.net·wpf·上位机·log4net
政沅同学6 天前
基于 C# WPF + HALCON 的工业视觉算法工具框架(开源)
开发语言·c#·wpf
happyprince6 天前
03_verl-设计理念与核心原理
wpf