预设置元素名字

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 元素的查找的更多相关文章

  1. WPF元素绑定

    原文:WPF元素绑定 数据绑定简介:数据绑定是一种关系,该关系告诉WPF从源对象提取一些信息,并用这些信息设置目标对象的属性.目标属性是依赖项属性.源对象可以是任何内容,从另一个WPF元素乃至ADO. ...

  2. Wpf使用Winform控件后Wpf元素被Winform控件遮盖问题的解决

    有人会说不建议Wpf中使用Winform控件,有人会说建议使用Winform控件在Wpf下的替代方案,然而在实际工作中由于项目的特殊需求,考虑到时间.成本等因素,往往难免会碰到在WPF中使用Winfr ...

  3. WPF 元素相对另外一个元素的 相对位置

    原文:WPF 元素相对另外一个元素的 相对位置 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/koloumi/article/details/740 ...

  4. UI自动化,通过Xpath结合父类、同级元素,查找到唯一的元素定位

    UI自动化,通过Xpath定位的总结 当页面展示的内容的html布局格式一样,只能第几个控件的绝对定位来区分时,如果后面有变更控件的顺序,就会导致找不到这个元素,维护成本较高,可以尝试用其他的方式,比 ...

  5. WPF元素可视化效果

    在WPF中设置元素的可视化效果主要用到BlurEffect类和DropShadowEffect类.(目前只学到这两个,哈哈) 1.BlurEffect类 命名空间: System.Windows.Me ...

  6. 学习WPF——元素绑定

    概念 从源对象提取一些信息,并用这些信息设置目标对象的属性 示例 在给TextBlock控件的FontSize属性赋值时,我们使用了绑定表达式 数据绑定表达式使用XAML的标记扩展(因此具有花括号)( ...

  7. WPF 元素绑定

    1.什么是数据绑定数据绑定是一种关系,WPF程序从源对象中提取一些信息,并根据这些信息设置目标对象的属性,目标属性作为依赖项属性.源对象可以是任何内容,可以是另一个wpf内容,甚至是自行创建的纯数据对 ...

  8. C++ 关联容器之map插入相同键元素与查找元素操作

    一.插入相同键元素操作 (1)insert方法 在map中的键必须是唯一的,当想map中连续插入键相同但值不同的元素时,编译和运行时都不会发生任何错误,系统会忽略后面的对已存在的键的插入操作,如 ma ...

  9. List<T>对元素的查找。

    要在List<T>中查找特定的元素,可以使用Contains() .IndexOf().LastIndexOf()和BinarySearch()方法.除了 LastIndexOf()是从最 ...

随机推荐

  1. GBDT理论知识总结

    一. GBDT的经典paper:<Greedy Function Approximation:A Gradient Boosting Machine> Abstract Function ...

  2. MacaW Baby Learns Computer

    A - Macaw Baby Learns Computer Time Limit:1000MS     Memory Limit:0KB     64bit IO Format:%lld & ...

  3. python yield yield from

    1.可迭代对象 具备可迭代的能力,即enumerable,在python中指的是可以通过for-in去逐个访问元素的一些对象,比如元组tuple,列表list,字符串string,文件对象file等. ...

  4. python 展开嵌套的序列

    将一个多层嵌套的序列展开成一个单层列表 可以写一个包含yield from 语句的递归生成器来轻松解决这个问题. from collections import Iterable def flatte ...

  5. OVS中的key解析

    OVS在处理每条流的时候,先根据每条流生产相应的key,然后根据key匹配相应的流表,根据流表中的action操作来处理每条流,本文对key的结构体进行分析,看看对于一条流会提出那些特征信息.对于ke ...

  6. Python2 和Python3 的差异总结

    一.基本语法差异 1.1 核心类差异 Python3对Unicode字符的原生支持 Python2中使用 ASCII 码作为默认编码方式导致string有两种类型str和unicode,Python3 ...

  7. linux常用命令:diff 命令

    diff 命令是 linux上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方.diff在命令行中打印每一个行的改动.最新版本的diff还支持二进制文件.diff程序的 ...

  8. Google、亚马逊、微软 、阿里巴巴开源软件一览

    Google.亚马逊.微软 .阿里巴巴开源软件一览 大公司为什么要发布开源项目?一是开源能够帮助他人更快地开发软件,促进世界创新,主要是社会价值层面的考虑.二是开源能够倒逼工程师写出更好的代码.三是开 ...

  9. HTML5 manifest离线缓存技术

    干什么用的? 离线缓存为的是第一次请求后,根据manifest文件进行本地缓存,并且在下一次请求后进行展示(若有缓存的话,无需再次进行请求而是直接调用缓存),最根本的感觉是它使得WEB从online可 ...

  10. JProfiler8 远程监控tomcat配置过程

    1. 阅读人群 1.熟悉liunx服务器,起码知道liunx常见的命令 2.熟悉tomcat容器,起码知道怎么tomcat的启动以及停止 3.熟悉java编程语言,JProfiler8是专门监控jav ...