WPF FindName()查找命名注册的元素

一、查找xaml中命名注册的元素

<Button x:Name="btn1" Content="显示内容"
                HorizontalAlignment="Left" Margin="25,115,0,0" VerticalAlignment="Top" Width="80" Height="60" Click="btn1_Click"/>
        <TextBox x:Name="txtOne" HorizontalAlignment="Left" Height="23"
                 Margin="25,62,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="80"/>
//使用FindName() 查找
TextBox txtOne = this.FindName("txtOne") as TextBox;
if (txtOne != null)
{
    MessageBox.Show(txtOne.Text); //可以访问到
}
TextBox txtTwo = btn1.FindName("txtOne") as TextBox;
if (txtTwo != null)
{
    MessageBox.Show(txtTwo.Text); //也可以访问到
}二、查找后台代码命名注册的元素后台添加方式
TextBlock block = new TextBlock();
block.Text = "海上生明月";
panelOne.RegisterName("block1", block); //将block命名block1名称注册到panelOne上
panelOne.Children.Add(block);
//从当前窗口获取,可以访问到
TextBlock block1 = btn1.FindName("block1") as TextBlock;
if (block1 != null)
{
    MessageBox.Show(block1.Text);
}
//从Panel获取,可以访问到
TextBlock block2 = panelOne.FindName("block1") as TextBlock;
if (block2 != null)
{
    MessageBox.Show("panelOne:"+block2.Text);
}注释:元素名称Name注册, 不能重复。

预设置元素名字

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(语法解析)的魔力,我们所看到的只能是表象.

不仅仅是注册元素的名字

除了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命名是有规定的,所以不要将其注册在内.
时间: 2024-08-06 16:02:43

WPF FindName()查找命名注册的元素的相关文章

WPF FindName()没找到指定名称的元素

1.FindName()说明,可以用来获取已经注册名称的元素或标签 // // 摘要: // 查找具有提供的标识符名的元素. // // 参数: // name: // 所请求元素的名称. // // 返回结果: // 请求的元素.如果未找到匹配的元素,该值将为 null. public object FindName(string name); 但是后台添加名称注册的方式是使用RegisterName(),而不是直接给Name赋值 // // 摘要: // 提供一个可简化对 System.Wi

在WPF中减少逻辑与UI元素的耦合

原文:在WPF中减少逻辑与UI元素的耦合             在WPF中减少逻辑与UI元素的耦合 周银辉 1,    避免在逻辑中引用界面元素,别把后台数据强加给UI  一个糟糕的案例 比如说主界面上有一个显示当前任务状态的标签label_TaskState,我们会时常更新该标签以便及时地将任务状态通知用户.那么很糟糕的一种假设是我们的代码中会到处充斥着这样的语句段this.label_TaskState .Content = this.GetStateDescription(TaskSta

【WPF学习】第三十章 元素绑定——绑定到非元素对象

原文:[WPF学习]第三十章 元素绑定--绑定到非元素对象 前面章节一直都在讨论如何添加链接两个各元素的绑定.但在数据驱动的应用程序中,更常见的情况是创建从不可见对象中提取数据的绑定表达式.唯一的要求是希望显示的信息必须存储在公有属性中.WPF数据绑定数据结构不能获取私有信息或公有字段. 当绑定到非元素对象时,需要放弃Binding.ElementName属性,并使用以下属性中的一个: Source:该属性是指向源对象的引用--换句话说,是提供数据的对象. RelativeSource:这是引用

PHP查找与搜索数组元素

in_array()函数 in_array()函数在一个数组汇总搜索一个特定值,如果找到这个值返回true,否则返回false.其形式如下: boolean in_array(mixed needle,array haystack[,boolean strict]); 来看下面的例子,查找变量apple是否已经在数组中,如果在,则输出一段信息: $fruit = "apple"; $fruits = array("apple","banana",

01:查找最接近的元素

http://noi.openjudge.cn/ch0111/01/ 01:查找最接近的元素 总时间限制:  1000ms 内存限制:  65536kB 描述 在一个非降序列中,查找与给定值最接近的元素. 输入 第一行包含一个整数n,为非降序列长度.1 <= n <= 100000.第二行包含n个整数,为非降序列各元素.所有元素的大小均在0-1,000,000,000之间.第三行包含一个整数m,为要询问的给定值个数.1 <= m <= 10000.接下来m行,每行一个整数,为要询问

在相邻元素相差1的数组中查找某一特定元素第一次出现的位置

题目:数组中相邻的每两个数之间的差值是1或-1,给定一个数N,求如何找到第一个N的位置. 如:3,4,3,2,1,2,3,4,3,4,5,6,5   求第一个5所在的位置. #include <stdio.h> #include <stdlib.h> int main(void) { int a[] = {3,4,3,2,1,2,3,4,3,4,5,6,5}; int i, next, to_search; int len = sizeof(a); int count = 0, f

在IFrame中查找IFRAME中的元素的方式

下面是内部iframe找外部mainFrame的情况 var websiteSearchButton = window.parent.parent.document.getElementById('mainFrame')     .contentWindow.document.getElementById("webresource-search-button"); iframe中1.子页面找符页面中的元素$(window.parent.document).find(id);2.父页面-

WPF中查找控件的扩展类

在wpf中查找控件要用到VisualTreeHelper类,但这个类并没有按照名字查找控件的方法,于是搜索网络,整理出下面这个类,感觉用起来很是方便. 贴出来,供大家参考. /// <summary> /// WPF/Silverlight 查找控件扩展方法 /// </summary> public static class VisualHelperTreeExtension { /// <summary> /// 根据控件名称,查找父控件 /// elementNa

[WPF]获取鼠标指针下的元素

原文:[WPF]获取鼠标指针下的元素   [WPF]获取鼠标指针下的元素 周银辉 以前写过一些GetElementUnderMouse之类的函数,要用到坐标换算而显得有些麻烦(特别是当元素有XXXTransform的时候) 今天看到Mouse类居然有一个DirectlyOver属性,可以获得鼠标下的元素, 很奇怪,我的MSDN文档以及VS2008智能提示中都没有显示该属性,但反编译一下可以看到. 但必须注意到的一点是,WPF控件是由各个元素复合而成的,但Mouse类可不知道这概念,所以不要期望它