我有一个用户控件,包含一个网格,包含一个子控件。
我想从用户控件后面的代码中获取对子控件的引用。
这就是我所拥有的:
var childControl = (MyChildControlType)this.Grid.Children.Single(c => (string) c.GetValue(NameProperty) == "MyChildControlNameFromXAMLNameAttribute");
像垃圾桶盖一样丑陋。
有什么更简洁的方法来做到这一点?
您可以按照已经建议的方式进行名称搜索:
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;
}
但实际上,如果您可以命名它并从代码隐藏中访问它,就像 John Bowen 所说的那样,那是迄今为止最简单的。
将 Name 或 x:Name 分配给 XAML 中的元素(除非它在模板内)使该元素可以作为具有该名称的字段从代码隐藏中访问。所以这基本上已经在 InitializeComponent 期间为您声明和填充:
MyChildControlType MyChildControlNameFromXAMLNameAttribute;
你可以直接使用它:
MyChildControlNameFromXAMLNameAttribute.Visibility = Visibility.Hidden;
可能是这样,将 x:Name 给您的 childControl
var childControl = (MyChildControlType)MyGridNameFromXAMLNameAttribute.FindName("MyChildControlNameFromXAMLNameAttribute");