本文将介绍 WPF 中 NameScope 的查找规则。(额外的,资源 / 资源字典的查找方式与 NameScope 的方式是一样的,所以本文分析过程同样使用与资源的查找。)
INameScope
WPF 的 INameScope 接口只用来管理一个范围之内的名称。它包含下面三个方法:
public interface INameScope
{
object FindName(string name);
void RegisterName(string name, object scopedElement);
void UnregisterName(string name);
}
它的主要实现是 NameScope,包含了更多功能;而上面的接口是其本2222质功能。
不过,NameScope 的实现带来了一个重要的依赖项属性 —— NameScope。下面是此属性的代码(经过简化):
public static readonly DependencyProperty NameScopeProperty
= DependencyProperty.RegisterAttached("NameScope", typeof(INameScope), typeof(NameScope));
public static void SetNameScope(DependencyObject dependencyObject, INameScope value)
{
if (dependencyObject == null) throw new ArgumentNullException(nameof(dependencyObject));
dependencyObject.SetValue(NameScopeProperty, value);
}
public static INameScope GetNameScope(DependencyObject dependencyObject)
{
if (dependencyObject == null) throw new ArgumentNullException(nameof(dependencyObject));
return ((INameScope)dependencyObject.GetValue(NameScopeProperty));
}
同样实现了此接口的还有 TemplateNameScope,此 NameScope 会被 FrameworkTemplate / FrameworkElementFactory / BamlRecordReader 设置到以上依赖属性中。于是我们可以在模板范围内找到某个特定名称对应的元素。
除此之外,NameScope 的设置由 XAML 解析器在 WPF 项目编译的时候自动生成。
NameScope 的名称注册规则
如果你没有在代码中显式去调用 RegisterName 这样的方法,那么 NameScope 的创建以及名称的注册都由 XAML 解析器来完成。










