问题
I have a UserControl called ZoneContainer
. This has a property that which contains a ListBox
containing a number of ListItem
s. Each ListItem contains a DockPanel
.
I'm trying to use a the following code to find the children that exist inside ZoneContainer
but childrenCount
is 0 every time.
var parent = this as DependencyObject; // I can see that this is populated.
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
Is there another way to find a specific child object inside a list of objects? Ultimately I'm trying to find the DockPanel, but it's not finding any children even though I know they're in the object.
回答1:
The basic problem here is that not all childs are part of the VisualTree
You can find more information about this problem in this articel from Josh Smith
here are my extension to get all Childs
public static IEnumerable<DependencyObject> getChilds(this DependencyObject parent)
{
if (parent == null) yield break;
//use the logical tree for content / framework elements
foreach (object obj in LogicalTreeHelper.GetChildren(parent))
{
var depObj = obj as DependencyObject;
if (depObj != null)
yield return depObj;
}
//use the visual tree for Visual / Visual3D elements
if (parent is Visual || parent is Visual3D)
{
int count = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < count; i++)
{
yield return VisualTreeHelper.GetChild(parent, i);
}
}
}
回答2:
This is the function I've got lurking in my library. I've never had any trouble with it, but it does have a GetChildrenCount() call in it so if that's not working for you you may have a bigger problem.
Public Shared Function FindVisualChild(Of T As DependencyObject)(ByVal element As DependencyObject) As T
If element Is Nothing Then
Return Nothing
ElseIf TypeOf (element) Is T Then
Return element
Else
Dim count = VisualTreeHelper.GetChildrenCount(element)
For index As Integer = 0 To count - 1
Dim child As DependencyObject = VisualTreeHelper.GetChild(element, index)
If TypeOf (child) Is T Then
Return child
Else
Dim grandchild As T = FindVisualChild(Of T)(child)
If grandchild IsNot Nothing Then Return grandchild
End If
Next
End If
Return Nothing
End Function
Usage: x = FindVisualChild(Of DockPanel)(ParentObject)
Yes, I know it's VB. It's about time one of you C# guys had to convert code for once! :)
回答3:
I resolved this issue by querying the objects rather than crawling the visual tree.
var header = container.ListBox.Items.Cast<ListBoxItem>()
.Select(item => (MyType) item.Content)
.FirstOrDefault(myType => myType.dpHeader.Name == "whatever").dpHeader;
来源:https://stackoverflow.com/questions/13248013/visualtreehelper-not-finding-children-of-dependencyobject-how-can-i-reliably-fi