查找子控件有以下几种方法
1.GetTemplateChild
2.FindName
GetTemplateChild
顾名思义GetTemplateChild通过名称查找控件,那么要查找的控件必须是通过实现
自定义ControlTemplate方式实现。
需要注意的是通过GetTemplateChild查找控件,必须在自定义控件内获取,如果在Winodw中使用该控件,在Window中是无法通过GetTemplateChild来查找该控件的。
如下我们自定义了一个控件CustomControl1
<Style TargetType="{x:Type controls:CustomControl1}">
<Setter Property="BorderBrush" Value="Gray"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid Background="AliceBlue" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="ControlTitleName" Grid.Row="0" FontSize="16" Text="{Binding Title, RelativeSource={RelativeSource TemplatedParent}}"/>
<TextBlock x:Name="ControlTitleSummary" Grid.Row="1" FontSize="12" Text="{TemplateBinding Summary}" Opacity="0.8"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
在CustomControl1.cs的实现文件中我们可以重载OnApplyTemplate函数内获取
ControlTitleName和ControlTitleSummary这两个TextBlock
GetTemplateChild("ControlTitleName") as TextBlock
GetTemplateChild("ControlTitleSummary") as TextBlock
FindName
该接口只能用于cs文件和xaml文件强关联的类中,比如像Window和自定义用户控件。
比如在Window.xaml中定义了名为WindowTestBlockName的TextBlock
<TextBlock Margin="5" Text="名称为TestBlockName" x:Name="WindowTestBlockName"/>
那么在Window.cs中就可以通过FindName来查找该TextBlock.
通过类型查找子控列表
/// <summary>
/// 通过某种类型查找子控件列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="parentObj">某个父控件</param>
/// <param name="typename">需要查找子控件类型</param>
/// <returns>查找到的子控件列表</returns>
public List<T> GetChildObjects<T>(DependencyObject parentObj, Type typename) where T : FrameworkElement
{
DependencyObject child = null;
List<T> childList = new List<T>();
for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(parentObj) - 1; i++)
{
child = VisualTreeHelper.GetChild(parentObj, i);
if (child is T && (((T)child).GetType() == typename))
{
childList.Add((T)child);
}
childList.AddRange(GetChildObjects<T>(child, typename));
}
return childList;
}
调用方式
List<TextBlock> listButtons = GetChildObjects<TextBlock>(ParentGridName, typeof(TextBlock));
通过名称来查找子控件列表
/// <summary>
/// 通过名称来查找子控件列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="parentObj">需要查找的父控件</param>
/// <param name="name">需要查找的控件名称</param>
/// <returns></returns>
public T GetChildObject<T>(DependencyObject parentObj, string name) where T : FrameworkElement
{
DependencyObject child = null;
T grandChild = null;
for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(parentObj) - 1; i++)
{
child = VisualTreeHelper.GetChild(parentObj, i);
if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name)))
{
return (T)child;
}
else
{
grandChild = GetChildObject<T>(child, name);
if (grandChild != null)
return grandChild;
}
}
return null;
}
调用
List<TextBlock> list2 = GetChildObjects<TextBlock>(ParentGridName, "SubName");
按名称查找子控件
/// <summary>
/// 按名称查找子控件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="parentObj">开始查找的父控件</param>
/// <param name="name">需要查找控件名称</param>
/// <returns></returns>
public List<T> GetChildObjects<T>(DependencyObject parentObj, string name) where T : FrameworkElement
{
DependencyObject child = null;
List<T> childList = new List<T>();
for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(parentObj) - 1; i++)
{
child = VisualTreeHelper.GetChild(parentObj, i);
if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name)))
{
childList.Add((T)child);
}
childList.AddRange(GetChildObjects<T>(child, name));
}
return childList;
}
调用
TextBlock sub = GetChildObject<TextBlock>(ParentGridName, "SubName");
按父控件名称查找父控件
/// <summary>
/// 按父控件名称查找父控件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj">锚点子控件</param>
/// <param name="parentName">父控件名称</param>
/// <returns>返回父控件</returns>
public T GetParentObject<T>(DependencyObject obj, string parentName) where T : FrameworkElement
{
DependencyObject parent = VisualTreeHelper.GetParent(obj);
while (parent != null)
{
if (parent is T && (((T)parent).Name == parentName | string.IsNullOrEmpty(parentName)))
{
return (T)parent;
}
parent = VisualTreeHelper.GetParent(parent);
}
return null;
}
调用
Grid sub2 = GetParentObject<Grid>(SubTextBlock, "ParentGridName");