在XAML中获取子控件的更聪明的方法是什么

本文关键字:更聪明 方法 是什么 控件 XAML 获取 | 更新日期: 2023-09-27 17:58:41

我有一个用户控件,包含一个网格,包含一个子控件。

我想从用户控件的代码后面获得对子控件的引用。

这就是我所拥有的:

var childControl = (MyChildControlType)this.Grid.Children.Single(c => (string) c.GetValue(NameProperty) == "MyChildControlNameFromXAMLNameAttribute");

丑得像被碾过的垃圾桶盖。

有什么更整洁的方法可以做到这一点?

在XAML中获取子控件的更聪明的方法是什么

您可以按照已经提出的建议进行名称搜索:

var childControl = (MyChildControlType)this.Grid.FindName("MyChildControlNameEtc");

或者,如果你想要一种更通用的方法来解决你已经在尝试的问题(例如,如果你想通过不同的属性查找),你可以尝试:

var childControl = (MyChildControlType)this.Grid.Children.OfType<FrameworkElement>().Single(f => f.Name == "Blah");

var childControl = (MyChildControlType)this.Grid.Children.OfType<MyChildControlType>().Single(f => f.Name == "Blah");

或者,您可以使用VisualTreeHelper,它可以与非网格一起工作,如果您需要向下递归可视化树,它将特别好地工作:

for(int i = 0; i < VisualTreeHelper.GetChildrenCount(this.Grid); ++i)
{
    var child = VisualTreeHelper.GetChild(this.Grid, i) as FrameworkElement;
    if (child != null && child.Name == "Blah")
        return child;
}

但实际上,如果你能像约翰·鲍恩所说的那样,从代码库中命名并访问它,那是迄今为止最简单的。

将Name或x:Name分配给XAML中的元素(除非它在模板内),可以使该元素作为具有该名称的字段从代码后面访问。因此,这基本上已经在InitializeComponent:期间为您声明和填充了

MyChildControlType MyChildControlNameFromXAMLNameAttribute;

你可以直接使用它:

MyChildControlNameFromXAMLNameAttribute.Visibility = Visibility.Hidden;

可能是这样,给你的孩子x:Name Control

 var childControl = (MyChildControlType)MyGridNameFromXAMLNameAttribute.FindName("MyChildControlNameFromXAMLNameAttribute");