I have an control in WPF which has an unique Uid. How can I retrive the object by its Uid?
Asked
Active
Viewed 1.5k times
17
-
1Please elaborate. What is your UID? How is it set? – Kent Boogaart Dec 11 '09 at 14:44
-
It is a dependency property of any control in wpf or silverlight .. i've managed to solve this, but i was wondering if exists a built-in method. – jose Dec 11 '09 at 16:33
4 Answers
14
You pretty much have to do it by brute-force. Here's a helper extension method you can use:
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;
}
Then you can call it like this:
var el = FindUid("someUid");

Matt Hamilton
- 200,371
- 61
- 386
- 320
-
Doesn't `GetChild(parent, N)` have the complexity of O(N) ? The foreach approach seems cleaner (and clearer) to me. – AgentFire Jun 03 '17 at 20:39
-
As [msdn](https://social.msdn.microsoft.com/Forums/en-US/9b5ff9c2-434a-4324-b896-350e995b645e/automationid-property?forum=vsautotest) states, if AutomationId is not set, WindowsAutomationFramework will default it to *Uid* if set, or to _ControlName_ if set (checked via inspect.exe). So in some cases the tooling for AutomationIds suffices. – RuNe Feb 11 '19 at 20:16
5
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;
}

pr0gg3r
- 4,254
- 1
- 36
- 27
2
This is better.
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;
}

SyntaxRules
- 2,056
- 23
- 32

Mike
- 623
- 6
- 26
-
It cannot be better if your code does not work. Your recursion is broken. The result of `el.FindUid(uid)`, if not null, must be returned. – jchristin Sep 29 '15 at 12:50
1
An issue I had with the top answer is that it won't look inside content controls (such as user controls) for elements within their content. In order to search inside these I extended the function to look at the Content property of compatible controls.
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;
}

Wilco
- 974
- 8
- 14