我们在 WPF 中使用绑定时可以使用 ElementName=Foo
这样的写法,并且还能够真的在运行时找到这个名称对应的对象,是因为 WPF 中提供了名称范围概念。
实现 INameScope
接口可以定义一个名称范围。无论你使用 Name
属性还是使用 x:Name
特性都可以在一个名称范围内指定某个元素的名称。绑定时就在此名称范围内查找,于是可以找到你需要的对象。
本文将介绍 WPF 中 NameScope 的查找规则。(额外的,资源 / 资源字典的查找方式与 NameScope 的方式是一样的,所以本文分析过程同样使用与资源的查找。)
INameScope
WPF 的 INameScope
接口只用来管理一个范围之内的名称。它包含下面三个方法:
public interface INameScope
{
object FindName(string name);
void RegisterName(string name, object scopedElement);
void UnregisterName(string name);
}
它的主要实现是 NameScope
,包含了更多功能;而上面的接口是其本质功能。
不过,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