Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何按类型获取WPF容器的子级?_C#_Wpf_Wpf Controls - Fatal编程技术网

C# 如何按类型获取WPF容器的子级?

C# 如何按类型获取WPF容器的子级?,c#,wpf,wpf-controls,C#,Wpf,Wpf Controls,如何在WPF中获取MyContainer中类型为ComboBox的子控件 <Grid x:Name="MyContainer"> <Label Content="Name" Name="label1" /> <Label Content="State" Name="label2" /> <ComboBox Height="23" HorizontalAlignment="Left" N

如何在WPF中获取MyContainer中类型为
ComboBox
的子控件

<Grid x:Name="MyContainer">                    
    <Label Content="Name"  Name="label1"  />
    <Label Content="State" Name="label2"  />
    <ComboBox Height="23" HorizontalAlignment="Left" Name="comboBox1"/>
    <ComboBox Height="23" HorizontalAlignment="Left" Name="comboBox3" />
    <ComboBox Height="23" HorizontalAlignment="Left" Name="comboBox4" />
</Grid>

子元素是元素的集合。因此,您需要迭代这些项,并确定每个项是否为所需类型。幸运的是,已经有了一个Linq方法,可以使用以下语法方便地调用:


此扩展方法将递归搜索所需类型的子元素:

public static T GetChildOfType<T>(this DependencyObject depObj) 
    where T : DependencyObject
{
    if (depObj == null) return null;

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
    {
        var child = VisualTreeHelper.GetChild(depObj, i);

        var result = (child as T) ?? GetChildOfType<T>(child);
        if (result != null) return result;
    }
    return null;
}
public static T GetChildOfType(此DependencyObject depObj)
其中T:DependencyObject
{
if(depObj==null)返回null;
for(int i=0;i

因此,使用它,您可以请求MyContainer.GetChildOfType()

搜索包含预定点(屏幕)的特定类型的第一个子项:

(参数“point”是调用“PointToScreen”函数(以可视类型声明)的结果)

private-tdescendattype-FindDescendant(DependencyObject父对象,点屏幕点)
其中tdescendattype:DependencyObject
{
int count=VisualTreeHelper.GetChildrenCount(父级);
for(int i=0;i
所有这些答案都很好,但是,如果你想找到一个特定的T型视觉子对象,你要么就得把它们都拿出来,然后再找到你想要的,要么就希望你得到的第一个就是你想要的。我合并了几种方法,以根据标准找到一种特定的方法。这有点像LINQ,但我不想尝试处理递归枚举器

像这样使用它:

MyContainer.FirstOrDefaultChild<Label>(l => l.Content=="State")
MyContainer.FirstOrDefaultChild(l=>l.Content==“State”)
我将其作为扩展方法编写

public static class DependencyObjectExtensions
{
    public static T FirstOrDefaultChild<T>(this DependencyObject parent, Func<T, bool> selector) 
        where T : DependencyObject
    {
        T foundChild;
        return FirstOrDefaultVisualChildWhere(parent, selector, out foundChild) ? foundChild : default(T);
    }

    private static bool FirstOrDefaultVisualChildWhere<T>(DependencyObject parent, Func<T, bool> selector,
        out T foundChild) where T : DependencyObject
    {
        var count = VisualTreeHelper.GetChildrenCount(parent);
        for (var i = 0; i < count; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);
            var tChild = child as T;
            if (tChild != null)
            {
                if (!selector(tChild)) continue;
                foundChild = tChild;
                return true;
            }

            if (FirstOrDefaultVisualChildWhere(child, selector, out foundChild))
            {
                return true;
            }
        }
        foundChild = default(T);
        return false;
    }
公共静态类DependencyObjectExtensions
{
公共静态T FirstOrDefaultChild(此DependencyObject父对象,Func选择器)
其中T:DependencyObject
{
发现儿童;
返回FirstOrDefaultVisualChildWhere(父级、选择器、OutFoundChild)?foundChild:默认值(T);
}
私有静态bool FirstOrDefaultVisualChildWhere(DependencyObject父对象、函数选择器、,
out T foundChild)其中T:DependencyObject
{
变量计数=VisualTreeHelper.GetChildrenCount(父级);
对于(变量i=0;i
所有这些答案,但其中一个使用了递归,这在IMO中很蹩脚:)

获取可视子对象:

public static IEnumerable<T> FindVisualChildren<T>([NotNull] this DependencyObject parent) where T : DependencyObject
{
    if (parent == null)
        throw new ArgumentNullException(nameof(parent));

    var queue = new Queue<DependencyObject>(new[] {parent});

    while (queue.Any())
    {
        var reference = queue.Dequeue();
        var count = VisualTreeHelper.GetChildrenCount(reference);

        for (var i = 0; i < count; i++)
        {
            var child = VisualTreeHelper.GetChild(reference, i);
            if (child is T children)
                yield return children;

            queue.Enqueue(child);
        }
    }
}
public static IEnumerable<T> FindLogicalChildren<T>([NotNull] this DependencyObject parent) where T : DependencyObject
{
    if (parent == null)
        throw new ArgumentNullException(nameof(parent));

    var queue = new Queue<DependencyObject>(new[] {parent});

    while (queue.Any())
    {
        var reference = queue.Dequeue();
        var children = LogicalTreeHelper.GetChildren(reference);
        var objects = children.OfType<DependencyObject>();

        foreach (var o in objects)
        {
            if (o is T child)
                yield return child;

            queue.Enqueue(o);
        }
    }
}
公共静态IEnumerable FindVisualChildren([NotNull]此DependencyObject父级),其中T:DependencyObject
{
如果(父项==null)
抛出新ArgumentNullException(nameof(parent));
var queue=new queue(new[]{parent});
while(queue.Any())
{
var reference=queue.Dequeue();
var count=VisualTreeHelper.GetChildrenCount(参考);
对于(变量i=0;i
获取逻辑子级:

public static IEnumerable<T> FindVisualChildren<T>([NotNull] this DependencyObject parent) where T : DependencyObject
{
    if (parent == null)
        throw new ArgumentNullException(nameof(parent));

    var queue = new Queue<DependencyObject>(new[] {parent});

    while (queue.Any())
    {
        var reference = queue.Dequeue();
        var count = VisualTreeHelper.GetChildrenCount(reference);

        for (var i = 0; i < count; i++)
        {
            var child = VisualTreeHelper.GetChild(reference, i);
            if (child is T children)
                yield return children;

            queue.Enqueue(child);
        }
    }
}
public static IEnumerable<T> FindLogicalChildren<T>([NotNull] this DependencyObject parent) where T : DependencyObject
{
    if (parent == null)
        throw new ArgumentNullException(nameof(parent));

    var queue = new Queue<DependencyObject>(new[] {parent});

    while (queue.Any())
    {
        var reference = queue.Dequeue();
        var children = LogicalTreeHelper.GetChildren(reference);
        var objects = children.OfType<DependencyObject>();

        foreach (var o in objects)
        {
            if (o is T child)
                yield return child;

            queue.Enqueue(o);
        }
    }
}
公共静态IEnumerable FindLogicalChildren([NotNull]此DependencyObject父对象),其中T:DependencyObject
{
如果(父项==null)
抛出新ArgumentNullException(nameof(parent));
var queue=new queue(new[]{parent});
while(queue.Any())
{
var reference=queue.Dequeue();
var children=LogicalTreeHelper.GetChildren(参考);
var objects=children.OfType();
foreach(对象中的var o)
{
if(o是T子级)
退换子女;
排队。排队(o);
}
}
}

请注意,如果您希望在第一次相遇时停止,请在
else
块中更改这两个代码以包含对
queue.Enqueue
的调用。

我发现了以下工作示例:

foreach (object o in LogicalTreeHelper.GetChildren(myWindow))
{
    if (o is SomeTypeOfMine)
    {
      //do something
    }
}

来源:

LogicalTreeHelper.FindLogicNode(DependencyObject depObj,string elementName)
为我实现了同样的目标。这不会在“ContentControlPlease”中搜索更多信息。仅代码和“try This”答案是,因为它们不包含可搜索的内容,并且不会解释为什么有人应该“尝试此”.我们在这里努力成为知识的资源。为什么递归是跛脚的?@Konrad
public static IEnumerable<T> FindLogicalChildren<T>([NotNull] this DependencyObject parent) where T : DependencyObject
{
    if (parent == null)
        throw new ArgumentNullException(nameof(parent));

    var queue = new Queue<DependencyObject>(new[] {parent});

    while (queue.Any())
    {
        var reference = queue.Dequeue();
        var children = LogicalTreeHelper.GetChildren(reference);
        var objects = children.OfType<DependencyObject>();

        foreach (var o in objects)
        {
            if (o is T child)
                yield return child;

            queue.Enqueue(o);
        }
    }
}
foreach (object o in LogicalTreeHelper.GetChildren(myWindow))
{
    if (o is SomeTypeOfMine)
    {
      //do something
    }
}