前两天在写一个WPF程序时,突然发现DataGrid控件没有筛选功能,但我不急,因为我知道,WPF的好处在于UI与逻辑的分离,要给数据网格控件加上输入筛选功能并不复杂,也不用去找第六方控件了,直接从DataGrid类派生一个类,并重定义它的控件模板,在DataGrid原有的控件模板上加一个StackPanel就可以了,方向为水平排列,放在列标头的下方。然后在代码中根据各个列的情况,向那个StackPanel添加N个文本框就可以输入筛选信息了。呵呵,虽不算完美,解决燃眉之急还是可以的。
这样我就想到另一个问题,如何修改DataTemplate里面的元素呢。或者说如何获取指定的元素。
于是,我在心里产生了两个方案:
1、在定义DataTemplate时,比如我里面用了一个TextBlock控件,我给它命名为tbText,然后我就循环访问集合控件的各个项,并得到每个项容器的ContentTemplate对象,希望用FindName方法直接把TextBlock取出来,但发生异常,这种方法不行。注意,如果DataTemplate定义在资源中,不能直接修改资源中的内容,因为这一改,会导致所有项都变了,因为集合控件(如ListBox)中每个项引用的都是同一个资源,而我现在要的是每个项里面的TextBlock的前景色都不一样。
2、我想到VisualTreeHelper类,对,就直接从项容器(ListBoxItem)的层次入手,一层一层往下找,直到找到TextBlock为止,由于我的模板中只有一个TextBlock,我就不必管它叫什么名字,只要是TextBlock类型就可以。但因为里面元素层次较多,不可能第一轮就能找到TextBlock,于是我写了一个递归方法,把元素的所有子元素都翻了个遍。
// 已修正 private void FindChildByType(DependencyObject relate, Type type, ref FrameworkElement resElement) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(relate); i++) { var el = VisualTreeHelper.GetChild(relate, i) as FrameworkElement; if (el.GetType() == type) { resElement = el; return; } else { FindChildByType(el, type, ref resElement); } } }
嘿嘿,这方法还果然骤效,为了使每个项的文本颜色不同,我使用了用随机数来创建颜色。
private Color BuildColor() { Array.Clear(colorBs, 0, colorBs.Length); rand.NextBytes(colorBs); return Color.FromRgb(colorBs[0], colorBs[1], colorBs[2]); }
好了,现在可以动手去改变DataTemplate中的元素的属性了。
/* 已修正 */
private void Button_Click_1(object sender, RoutedEventArgs e) { foreach (var item in lb.Items) { var el = lb.ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement; if (el != null && el is ListBoxItem) { ListBoxItem lbItem = el as ListBoxItem; FrameworkElement efind = default(FrameworkElement); FindChildByType(lbItem, typeof(TextBlock), ref efind); if (efind is TextBlock) { TextBlock textblock = efind as TextBlock; textblock.Foreground = new SolidColorBrush(BuildColor()); } } } }
把每个项的TextBlock找出来,修改它的Foreground属性。
我们可以在找到TextBlock后的代码上下一个断点,然后调试运行。代码执行到断点处停下,把鼠标移到TextBlock变量上,点击名字右边的放大镜图标,从弹出的菜单中选择【WPF Tree Visualizer】。如下图所示。
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索控件
, 元素
, TextBlock
, datatemplate
一个
wpf查找控件的子元素、wpf 查找子元素实例、wpf 模板、wpf 控件模板、wpf 界面模板,以便于您获取更多的相关知识。