本文写的如何动态查找ItemTemplate里的控件。像ListView,GridView,FlipView等控件可以通过自定义ItemTemplate来更好呈现每一个item的内容。也许你觉得可以通过绑定来实现自动改变值,不需要动态查找ItemTemplate里的控件。我可以说确实如此。但是本文提供的是另一种思路,动态查找ItemTemplate里的控件,从而达到对相应控件进行操作的目的。
首先我们要知道为什么不能直接给ItemTemplate的控件添加“Name”或“x:Name”属性,这样就可以通过名字直接找到对应控件。那是因为像ListView之类的控件一般都会有很多Item,而每个Item的ItemTemplate都是一样的。我们无法为每个Item对应的Template里的控件命名。但是有的时候又非得找到某个Item对应Template里的某个控件,并对其进行操作。不废话,直接贴代码:
private childItem FindVisualChild<childItemType>(DependencyObject obj)
where childItemType : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is childItemType)
return (childItemType)child;
else
{
childItem childOfChild = FindVisualChild<childItemType>(child);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}
相信大家一看就知道了,这段主要通过VisualTreeHelper这个来递归查找子元素。其中childItemType就是查找的ItemTemplate
里的某个控件的类型,而传入参数obj就是这个ItemTemplate对应的某个Item。下面再来看看如何使用这个函数:
var item = salesStage.ItemContainerGenerator.ContainerFromIndex(i);
//这里的salesStage是一个GridView,通过salesStage.ItemContainerGenerator和它的某个Item的Index,就可以找到这个Item所对应的Container(其实也就是Template)。
var stackPanel = FindVisualChild<StackPanel>(item);
//然后我们将这个找到的item作为参数调用前面的函数,我这里找的是StackPanel,这样的就能够找到Template下StackPanel了哦,当然如果有多个相同控件的,就需要通过循环自己去控制找哪个了哦。