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;
}
相关推荐
Marzlam1 小时前
一文读懂WPF系列之依赖属性与附加属性
wpf
zxb11c3 小时前
WPF 中的元素继承层次结构 ,以下是对图中内容的详细说明:
wpf
Zhen (Evan) Wang3 小时前
Margin和Padding在WPF和CSS中的不同
css·wpf
Marzlam21 小时前
一文读懂WPF布局
wpf
WineMonk1 天前
.NET WPF 控件类分层结构
.net·wpf
Marzlam1 天前
一文读懂WPF系列之控件模版数据模板
wpf
界面开发小八哥3 天前
界面控件DevExpress WPF v25.1新功能预览 - 数据网格、报表性能增强
wpf·界面控件·devexpress·ui开发·.net 9
WineMonk4 天前
.NET WPF 可视化树(Visual Tree)
.net·wpf
ALex_zry4 天前
构建高可靠C++服务框架:从日志系统到任务调度器的完整实现
开发语言·c++·wpf
Bruce_Cheung5 天前
WPF旋转板栈设计一例
wpf·rack·tube·料盒·料管