信息
您所需的主题如下所示。但此主题未包含在此库中。

FrameworkElement.FindName 方法

2013/12/13

检索具有指定标识符名称的对象。

Namespace:  System.Windows
程序集:  System.Windows(位于 System.Windows.dll 中)

声明
Public Function FindName ( _
	name As String _
) As Object

参数

name
类型: System.String
已请求对象的名称。

返回值

类型: System.Object
请求的对象。 如果在当前 XAML 命名空间中未找到匹配的对象,则可以为 Nothing

重要说明重要说明:

为了有效使用 FindName 方法,应了解 XAML 名称范围的概念和 XAML 名称范围在 XAML 加载时的创建方式,及其后在运行时可能的引用和修改方式。

下面汇总了一些重要的 XAML 名称范围概念:

  • 运行时 API(如 FindName)根据对象树工作。 这些对象会加载到整个内容区域和 CLR 运行时引擎中。 当从模板创建对象树的一部分或运行时加载 XAML 时,XAML 名称范围通常不与整个该对象树相邻。 结果是对象树中可能有一个给定 FindName 调用找不到的命名对象。

  • 在典型应用程序方案中,可能会在以下情况下遇到 XAML 名称范围之间的断点:通过应用模板创建对象时,或通过调用 XamlReader.Load 创建对象并随后将其添加到主对象树中时。

  • 如果为 FindName 返回意外的空结果,可以使用以下技术查找您感兴趣的命名对象:

    • 对于来自模板的命名对象,如果您正在编写控件,则可以从应用模板的对象范围调用 GetTemplateChild。 必须位于派生类定义作用域中,以便使用 GetTemplateChild,因为它是受保护的 Control 方法。

    • 如果您不在派生类定义作用域内,您可以在应用模板后在对象生存期中的某个点通过使用 VisualTreeHelper 进入模板的可视化树。 但是,VisualTreeHelper 使用父-子比喻在树中移动,而不是使用 XAML 名称范围概念。 遍历树通常需要控件组合的特定知识,因为它来自给定模板。

    • 对于 XamlReader.Load 事例,保留对 XamlReader.Load 调用的返回值的引用,该引用是将成为创建的相关 XAML 名称范围所有者或基础的对象。 然后改为从该范围调用 FindName

FindName 返回的对象不一定是一个 FrameworkElement。 例如,您可能对动画演示图板应用了某一名称,而各种动画演示图板类型并不是从 FrameworkElement 派生的。

通过在 XAML 标记中对对象元素指定特性来分配对象的 Name 属性(或等效 x:Name XAML 指令)。 可以在加载初始源 XAML 后设置 Name 值,但此方法有一些限制(请参见 Name 中的“备注”)。 可以为针对 Load 的调用指定 Name,作为 XAML 输入一部分;但请注意,这样创建的名称将位于离散 XAML 名称范围内,该名称范围只能延伸到所提供 XAML 输入的根等效部分。 如果在调用 Load 后随即将创建的对象添加到主对象树,上述注意事项将影响您如何调用 FindName 以及应该从哪一编程范围调用它。

TextElement 定义类似的 FindName。 这将在 Windows Phone 文本对象模型中启用 FindName 行为,该模型不基于 FrameworkElement。 通过以上任一种 FindName 实现进行调用都可以遍历到混合的 FrameworkElement/文本元素对象树,并且使用通用 XAML 名称范围,这样 FrameworkElement.FindName 调用就可以找到指定的文本元素,反之亦然。

对象树中在运行时添加的或更改的 Name 值将更新为对象树中该级别的操作 XAML 名称范围。 换言之,如果您创建新的 FrameworkElement,赋予它 Name,然后将其添加到对象树,从该 XAML 命名范围调用 FindName 可以找到和返回该代码创建的对象。

说明注意:

模板化的控件通常使用 GetTemplateChild(而不是使用 FindName)查找其模板的已命名部件,作为其 OnApplyTemplate 重写的一部分。 这是从 XAML 定义的模板联接类逻辑和元素引用所必需的。

下面的示例使用 FindName 从刚刚作为组件加载的 XAML 页查找命名元素。 在此情况下,不能只是引用命名元素作为其字段引用,因为缺少对通常生成的 InitializeComponent 的调用,该字段不存在。


Private LayoutRoot As System.Windows.Controls.Grid

Public Sub New()
    System.Windows.Application.LoadComponent(Me, New System.Uri( _
        "/WindowsPhoneApp1;component/Page.xaml", _
        System.UriKind.Relative))
    Me.LayoutRoot = CType(Me.FindName("LayoutRoot"),  _
        System.Windows.Controls.Grid)
End Sub


(如果从 Windows Phone 页的 XAML 编译内部版本操作生成的代码检查 InitializeComponent 的实际定义,可以看到类似代码。 请注意连续的 FindName 调用,这些调用为每个命名的元素分配字段引用值,并因此使这些字段引用可供代码隐藏中的任何运行时调用使用。)

Windows Phone OS

受以下版本支持: 8.0, 7.1, 7.0

Windows Phone

显示: