Получить объект по его Uid в WPF

У меня есть элемент управления в WPF, который имеет уникальный Uid. Как я могу восстановить объект по его Uid?

Ответ 1

Вы в значительной степени должны это делать грубой силой. Здесь вы можете использовать вспомогательный метод расширения:

private static UIElement FindUid(this DependencyObject parent, string uid)
{
    var count = VisualTreeHelper.GetChildrenCount(parent);
    if (count == 0) return null;

    for (int i = 0; i < count; i++)
    {
        var el = VisualTreeHelper.GetChild(parent, i) as UIElement;
        if (el == null) continue;

        if (el.Uid == uid) return el;

        el = el.FindUid(uid);
        if (el != null) return el;
    }
    return null;
}

Затем вы можете вызвать его так:

var el = FindUid("someUid");

Ответ 2

Это лучше.

public static UIElement FindUid(this DependencyObject parent, string uid) {
    int count = VisualTreeHelper.GetChildrenCount(parent);

    for (int i = 0; i < count; i++) {
        UIElement el = VisualTreeHelper.GetChild(parent, i) as UIElement;
        if (el != null) {
            if (el.Uid == uid) { return el; }
            el = el.FindUid(uid);
        }
    }
        return null;
}

Ответ 3

public static UIElement GetByUid(DependencyObject rootElement, string uid)
{
    foreach (UIElement element in LogicalTreeHelper.GetChildren(rootElement).OfType<UIElement>())
    {
        if (element.Uid == uid)
            return element;
        UIElement resultChildren = GetByUid(element, uid);
        if (resultChildren != null)
            return resultChildren;
    }
    return null;
}

Ответ 4

Проблема, с которой я столкнулся с лучшим ответом, заключается в том, что она не будет рассматривать элементы управления содержимым (например, пользовательские элементы управления) для элементов в своем контенте. Чтобы выполнить поиск внутри них, я расширил функцию, чтобы посмотреть свойство Content совместимых элементов управления.

public static UIElement FindUid(this DependencyObject parent, string uid)
{
    var count = VisualTreeHelper.GetChildrenCount(parent);

    for (int i = 0; i < count; i++)
    {
        var el = VisualTreeHelper.GetChild(parent, i) as UIElement;
        if (el == null) continue;

        if (el.Uid == uid) return el;

        el = el.FindUid(uid);
        if (el != null) return el;
    }

    if (parent is ContentControl)
    {
        UIElement content = (parent as ContentControl).Content as UIElement;
        if (content != null)
        {
            if (content.Uid == uid) return content;

            var el = content.FindUid(uid);
            if (el != null) return el;
        }
    }
    return null;
}