我需要在WPF控件层次结构中搜索与给定名称或类型匹配的控件。我该怎么做呢?


当前回答

试试这个

<TextBlock x:Name="txtblock" FontSize="24" >Hai Welcom to this page
</TextBlock>

后面的代码

var txtblock = sender as Textblock;
txtblock.Foreground = "Red"

其他回答

我能够找到对象的名称使用下面的代码。

stkMultiChildControl = stkMulti.FindChild(“<StackPanel>stkMultiControl_” + couter.ToString());

我找不到@CrimsonX或@Drew Noakes方法的控件,因为我的ControlTemplate位于一个单独的XAML文件中。 我用下面的方法找到了控件:

private Image backImage;
private void Diagram_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
    // here is the example of the ControlTemplate declaration
    //<ControlTemplate x:Key="DiagramControlTemplate1" TargetType="{x:Type Diagram}">
    var ctrlTemplate = (ControlTemplate)FindResource("DiagramControlTemplate1");
    // diagram is the x:Name of TemplatedControl and, "backImage" is the name of control that I want to find.
    var imageControl = ctrlTemplate.FindName("backImage", diagram);
    if (imageControl != null)
    {
        this.backImage = (Image)imageControl;
    }
}

这对我很有用。

试试这个

<TextBlock x:Name="txtblock" FontSize="24" >Hai Welcom to this page
</TextBlock>

后面的代码

var txtblock = sender as Textblock;
txtblock.Foreground = "Red"

下面是一个使用灵活谓词的解决方案:

public static DependencyObject FindChild(DependencyObject parent, Func<DependencyObject, bool> predicate)
{
    if (parent == null) return null;

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

        if (predicate(child))
        {
            return child;
        }
        else
        {
            var foundChild = FindChild(child, predicate);
            if (foundChild != null)
                return foundChild;
        }
    }

    return null;
}

例如,你可以这样称呼它:

var child = FindChild(parent, child =>
{
    var textBlock = child as TextBlock;
    if (textBlock != null && textBlock.Name == "MyTextBlock")
        return true;
    else
        return false;
}) as TextBlock;

下面是我的代码,通过类型来查找控件,同时控制我们进入层次结构的深度 (maxDepth == 0表示无限深)。

public static class FrameworkElementExtension
{
    public static object[] FindControls(
        this FrameworkElement f, Type childType, int maxDepth)
    {
        return RecursiveFindControls(f, childType, 1, maxDepth);
    }

    private static object[] RecursiveFindControls(
        object o, Type childType, int depth, int maxDepth = 0)
    {
        List<object> list = new List<object>();
        var attrs = o.GetType()
            .GetCustomAttributes(typeof(ContentPropertyAttribute), true);
        if (attrs != null && attrs.Length > 0)
        {
            string childrenProperty = (attrs[0] as ContentPropertyAttribute).Name;
            foreach (var c in (IEnumerable)o.GetType()
                .GetProperty(childrenProperty).GetValue(o, null))
            {
                if (c.GetType().FullName == childType.FullName)
                    list.Add(c);
                if (maxDepth == 0 || depth < maxDepth)
                    list.AddRange(RecursiveFindControls(
                        c, childType, depth + 1, maxDepth));
            }
        }
        return list.ToArray();
    }
}