WPF 元素的查找
预设置元素名字
WPF有两种方式设置元素的Name
<StackPanel x:Name="panel">
<Label Name="name1" Content="Name1Label"/>
<Label x:Name="name2" Content="Name2Label"/>
</StackPanel>
这里我们的重点不在于讨论Name和x:Name的区别,
Name是真正元素上的属性,x:Name而则xaml(语法解析)的魔力,我们所看到的只能是表象.
查找已设置Name的元素
WPF的基类元素FrameworkElement提供了FindName方法以提供查找设定的元素
![]()
以Code的形式添加元素
var label = new Label();
label.Name = "label3";
panel.Children.Add(label);
注意已经设置了Name
添加好以后,然后查找这个元素,会发现并不能查找到这个元素
![]()
上面就说过xaml是有魔力的,并非设置一个Name属性就可以了的,其内部还有了一个叫RegisterName的方法,以注册元素的Name(想象一下,如果有1000个树节点,从根节点开始找最内部的节点那得多慢),有了Name就跟元素绑到一起了.
现修改如下,用RegisterName方法注册(注意:即使注释了Name 属性也不会有影响)
var label = new Label();
// label.Name = "label3";
this.RegisterName("label3", label);
panel.Children.Add(label);
现在查找恢复成功
![]()
但会发现查找出来的元素Name还是空的.这就会造成歧义,建议应该Name属性和RegisterName方法一起设置,
不仅仅是注册元素的名字
除了Element之外,其他类型也是可以的,如
<Label>
<Label.BorderBrush>
<SolidColorBrush x:Name="brushName"></SolidColorBrush>
</Label.BorderBrush>
</Label>
有些基本类型在xaml中无法设置,如String,Int类型等.但可以通过代码设置
this.RegisterName("str", "Hello");
这里只有功能示例而已,但实际中千万别这么做,本身不为此设计.
查找UserControl的元素
先定义一个UserControl
<UserControl x:Class="NameScopeDemo.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Button HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="btn">UserControl Button</Button>
</Grid>
</UserControl>
在主窗体中使用UserControl
<StackPanel x:Name="panel">
<local:MyUserControl x:Name="myControl"></local:MyUserControl>
</StackPanel>
现在查找结果如下
![]()
若使用主窗体去无法查找到btn的话,但通过UserControl就可以.
在设计上将UI切分了,但却给查找元素造成了麻烦了。
命名范围(NameScope)
若以Code方式,添加方式则如下
uc = new MyUserControl();
var ns = new NameScope();
this.RegisterName("myControl", uc);
panel.Children.Add(uc);
为UserControl创建了一个独立的命名范围,想要查找MyUserControl的元素可以通过MyUserControl的级别的FindName来查找
模板取元素
<ContentControl x:Name="cc">
<ContentControl.ContentTemplate>
<DataTemplate>
<Button HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="btn">UserControl Button</Button>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
看到上面代码,cc无法通过FindName查找到btn,只有模板的根元素才可以,这个根元素一般是ContentPresenter,所以当在模板内查找元素时,必须告诉其根元素
public Object FindName(
string name,
FrameworkElement templatedParent
)
那么首先我们就必须找到ContentPresenter,而只能通过视觉树上面找,整体而言还是比较麻烦的,不知道为何内部API不封装一下.
将模板内的元素名字注册到父级
var ns = uc.GetValue(NameScope.NameScopeProperty) as IDictionary<string, object>;
var localNS = this.GetValue(NameScope.NameScopeProperty) as IDictionary<string, object>;
foreach (var n in ns)
{
if (localNS.ContainsKey(n.Key))
{
this.RegisterName(n.Key, n.Value);
}
}
首先获取当前元素的NameScope,然后再将其注册到父级命名范围内以方便查找,值得注意的是模板内部的有些Name是固定的,如ScrollBar,其内部模板元素Name命名是有规定的,所以不要将其注册在内.
下篇将继续讨论NameScope,绑定,视觉树,逻辑树之间的关系
WPF 元素的查找的更多相关文章
- WPF元素绑定
原文:WPF元素绑定 数据绑定简介:数据绑定是一种关系,该关系告诉WPF从源对象提取一些信息,并用这些信息设置目标对象的属性.目标属性是依赖项属性.源对象可以是任何内容,从另一个WPF元素乃至ADO. ...
- Wpf使用Winform控件后Wpf元素被Winform控件遮盖问题的解决
有人会说不建议Wpf中使用Winform控件,有人会说建议使用Winform控件在Wpf下的替代方案,然而在实际工作中由于项目的特殊需求,考虑到时间.成本等因素,往往难免会碰到在WPF中使用Winfr ...
- WPF 元素相对另外一个元素的 相对位置
原文:WPF 元素相对另外一个元素的 相对位置 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/koloumi/article/details/740 ...
- UI自动化,通过Xpath结合父类、同级元素,查找到唯一的元素定位
UI自动化,通过Xpath定位的总结 当页面展示的内容的html布局格式一样,只能第几个控件的绝对定位来区分时,如果后面有变更控件的顺序,就会导致找不到这个元素,维护成本较高,可以尝试用其他的方式,比 ...
- WPF元素可视化效果
在WPF中设置元素的可视化效果主要用到BlurEffect类和DropShadowEffect类.(目前只学到这两个,哈哈) 1.BlurEffect类 命名空间: System.Windows.Me ...
- 学习WPF——元素绑定
概念 从源对象提取一些信息,并用这些信息设置目标对象的属性 示例 在给TextBlock控件的FontSize属性赋值时,我们使用了绑定表达式 数据绑定表达式使用XAML的标记扩展(因此具有花括号)( ...
- WPF 元素绑定
1.什么是数据绑定数据绑定是一种关系,WPF程序从源对象中提取一些信息,并根据这些信息设置目标对象的属性,目标属性作为依赖项属性.源对象可以是任何内容,可以是另一个wpf内容,甚至是自行创建的纯数据对 ...
- C++ 关联容器之map插入相同键元素与查找元素操作
一.插入相同键元素操作 (1)insert方法 在map中的键必须是唯一的,当想map中连续插入键相同但值不同的元素时,编译和运行时都不会发生任何错误,系统会忽略后面的对已存在的键的插入操作,如 ma ...
- List<T>对元素的查找。
要在List<T>中查找特定的元素,可以使用Contains() .IndexOf().LastIndexOf()和BinarySearch()方法.除了 LastIndexOf()是从最 ...
随机推荐
- 干货:Java并发编程系列之volatile(二)
接上一篇<Java并发编程系列之synchronized(一)>,这是第二篇,说的是关于并发编程的volatile元素. Java语言规范第三版中对volatile的定义如下:Java编程 ...
- C/C++笔记 #035# Makefile
相关资料: Understanding roles of CMake, make and GCC GCC and Make ( A simple tutorial, teaches u how to ...
- Python Web学习笔记之Cookie,Session,Token区别
一.Cookie,Session,Token简介 # 这三者都解决了HTTP协议无状态的问题 session ID or session token is a piece of data that i ...
- linux不常用但很有用的命令(持续完善)
Linux登录后设置提示信息: /etc/issue 本地端登录前显示信息文件 /etc/issue.net 网络端登录前显示信息文件 /etc/motd 登陆后显示信息文件 可以添加以下几个常用选项 ...
- ELK之elasticsearch6.5集群
前面介绍并初试了es6.5系列的单节点的操作,现在搭建es6.5系列的集群: 环境:三节点:master-172.16.23.128.node1-172.16.23.129.node2-172.16. ...
- 20145206邹京儒 EXP7网络欺诈技术防范
20145206邹京儒 EXP7网络欺诈技术防范 一.实践过程记录 URL攻击实验前准备 1.在终端中输入命令:netstat -tupln |grep 80,查看80端口是否被占用,如下图所示 2. ...
- 20145302张薇《课程设计》数据恢复——WinHex实践
20145302张薇<课程设计>数据恢复--WinHex实践 实践内容 使用WinHex破损一个U盘 使用WinHex通过DBR备份数据来修复已损坏U盘 实践详细步骤 1.准备一个文件格式 ...
- Bof基础实践
Bof基础 Bof原理 Linux下进程地址空间的布局 典型的堆栈结构 上图中可以看到栈中有return address还有局部变量,也就是函数的参数,bof攻击是利用上参数的溢出将返回地址retur ...
- noip 2014 提高组 Day 2
1.无线网络发射器选址 这道题数据范围很小,就直接暴力枚举就好了.为了提高速度,就从每个有公共场所的点枚举周围在(x,y)放无线网路发射器可以增加的公共场所数量,加到一个数组里.所有公共场所都处理完了 ...
- linux平台关闭某个进程的脚本
在开发LINUX平台下的程序时,经常需要为我们的开发的程序写启动程序和关闭程序的脚本. 启动脚本比较好做,关闭程序脚本如下: 具体思路是通过ps命令找到程序的进程ID号,然后通过Kill命令将程序Ki ...