WPF中如何查找数据模板中的子元素

前两天在写一个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 界面模板,以便于您获取更多的相关知识。

时间: 2024-10-16 00:09:22

WPF中如何查找数据模板中的子元素的相关文章

C# dataset 怎么查找数据列中是否存在某个值?

问题描述 C# dataset 怎么查找数据列中是否存在某个值? dataset 怎么查找数据列中是否存在某个值?举例说明 A b c 110 2 3 105 58 99 125 56 80 查找a列是否存在180值? 解决方案 System.Data.DataSet ds = new System.Data.DataSet(); System.Data.DataTable dt = ds.Tables[0];//如果是其他表注意修改下标 System.Data.DataView dv = dt

matlab中如何提取数据文件中的特定行和列?

问题描述 matlab中如何提取数据文件中的特定行和列? 一个数据文件,我想提取它的第一到第四列,以及第九列 和第1到500行,以及501到1000行? 解决方案 data = []; data = original(:,1:4);其他类似

js中如何对django模板中的变量进行赋值

问题描述 js中如何对django模板中的变量进行赋值 问题是这样的: 在views.py文件中,文件如下: def index(req): company_contact = '联系我们' company_about = '关于我们' company = "" return render_to_response("about.html", locals()) 我希望根据当前网页的地址是以about结尾,还是contact结尾,来分别对company赋予comoan

Sql Server中清空所有数据表中的记录_MsSql

Sql Server中清空所有数据表中的记录 清空所有数据表中的记录: 复制代码 代码如下: exec sp_msforeachtable  @Command1 ='truncate table ?' 删除所有数据表: 复制代码 代码如下: exec sp_msforeachtable 'delete   N''?''' 清空SQL Server数据库中所有表数据的方法(有约束的情况) 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之

DTD文件中,如何在两个不同子元素中声明相同的子元素

问题描述 DTD文件中,如何在两个不同子元素中声明相同的子元素 JenniferWidom JerryR.Cain 比如如何声明 First_Name,Last_Name

Sql Server中清空所有数据表中的记录

清空所有数据表中的记录: exec sp_msforeachtable  @Command1 ='truncate table ?' 删除所有数据表: exec sp_msforeachtable 'delete   N''?'''

webuploader-WebUploader中的uploadSuccess是自动调用的吗?怎么获取服务器中返回的数据?

问题描述 WebUploader中的uploadSuccess是自动调用的吗?怎么获取服务器中返回的数据? WebUploader中的uploadSuccess是自动调用的吗?怎么获取服务器中返回的数据? 我图片上传成功服务器也收到图片了,但是返回的数据前台接收不到,也没有执行uploadSuccess方法,这是怎么回事?各位大神,求助! 解决方案 服务器会返回success(200)状态码,表示成功.你也可以自己处理onsuccess,把你的接收的代码写进去. 返回的数据前台接收不到 你要注意

用wp抠图-如何把wps的ppt模板中图抠出来用

问题描述 如何把wps的ppt模板中图抠出来用 想要用wps中给的ppt模板中的某一张中的图片或图形,和制作一个动态背景,要怎么把它抠出来,并且制作一个动态背景? 解决方案 午端阳粽飘香端午节PPT模板

继承-关于父类中private的数据

问题描述 关于父类中private的数据 父类中private的成员方法,在子类中无法重写要怎样理解哦~ 解决方案 访问权限为private 的方法是无法被重写的 举个列子 你找你爸要生活费 父亲持有生活费这个变量 关系是私有 子类不能重写,因为父亲不愿意 你要是直接调用父亲的钱还了得 所以父亲提供一个公开的方法,比如get,set 让你去操作 你想操作父亲的钱,必须用父亲提供的方法 解决方案二: private是私有方法,要重写就得是public方法 解决方案三: "在子类中可以重新写一个与父