预设置元素名字

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. java 事件通告写法

    使用场景: 自己模块发生变化后可能引起其他模块变化的部分,需要添加事件通告,通知其他模块. 使用模式: 观察者模式 (以User类为例)写法: 1.创建接口: public interface IUs ...

  2. Trove系列(三)—Trove的功能管理功能介绍

    Trove的功能管理功能Trove的功能管理功能包括给各种不同的版本的 datastore 安装不同的 功能. 本管理功能只适用于激活/去活全系统的功能.唯一例外的是数据存储功能列表功能,该功能对所有 ...

  3. EditPlus 4.3.2543 中文版已经发布(2月3日更新,Emmet 功能回归)

    新的 EditPlus 版本修复了 Emmet 组件的安全问题. 现在 Emmet 编辑功能又回来啦. 下载连接在页面左上角!

  4. 生产者消费者模型——wait/notify/notifyAll使用

    告警系统架构如下 1. 数据处理系统处理完原始数据并入库后,发送消息到kafka系统: 2. 告警生产者从kafka系统查询消息存入告警消息队列: 3. 告警消费者从告警消息队列查询消息进行处理. 这 ...

  5. redis安装 phpredis Jedis 扩展的实现及注意事项,php,java,python相关插件安装实例代码和文档推荐

    redis安装 phpredis Jedis 扩展的实现及注意事项,php,java,python相关插件安装实例代码和文档推荐 1.Redis 官方网站下载: http://redis.io/dow ...

  6. php 字符串长度函数

    php 字符串长度函数 php 字符串长度函数,在php测试字符串长度的函数有二个,一个是strlen,另一个是mb_strlen前一个默认是支持,后一个需要开启一个插件,下面我们来介绍一下二个函数的 ...

  7. Jmeter--正则表达式提取器

    正则提取器的一般使用场景是, 在我第二个请求参数中需要加入第一个请求的返回值, 此时通过正则提取器可以提取第一个请求返回值中指定的字段信息并赋值, 在第二个请求参数中直接引用该变量即可 jmeter的 ...

  8. 0-5v转0-20ma和0-5v转4-20ma

    0-5v转0-20ma 0-5v转4-20ma

  9. Quartz框架调用——运行报错:ThreadPool class not specified

    Quartz框架调用——运行报错:ThreadPool class not specified 问题是在于Quartz框架在加载的时候找不到quartz.properties配置文件: 解决方案一: ...

  10. 20145306 张文锦 网络攻防 web基础

    20145306 网络攻防 web基础 实验内容 WebServer:掌握Apache启停配置修改(如监听端口)前端编程:熟悉HTML+JavaScript.了解表单的概念编写不同的HTML网页,放入 ...