2015-08-29 33 views
3

在XAML解析的上下文中,我想知道解析器如何知道类型何时定义了一个NameScope。XAML解析器如何识别NameScopes?

它完全依赖于INameScope接口,检查instance is INameScope

它是否依赖布尔属性XamlType.IsNameScope?

这是两者的混合?

+4

如果您澄清了“_the parser_”的含义,这将有所帮助。据我所知_XAML_是一种语言,并不意味着使用任何特定的解析器。我只能猜测你指的是_WPF_框架使用的那个,但即使这样也至少要指定它的版本。否则,如果它不是一个解析器的具体问题,答案将是“这取决于实施”。 – Grx70

回答

6

微软文档有这方面的一些良好的信息:

缺省情况下由.NET框架XAML服务API一起使用时,主XAML名称范围在单个XAML生产XAML根元素定义并且包含该XAML制作中包含的元素。

这里的东西是任何Xaml文档中的根元素都有一个为它创建的名称范围。发生这种情况无论的元素是否实现了INameScope(实际上,没有核心UI元素)。

单个XAML生产中可能出现的额外离散XAML名称范围可以由框架定义以解决特定情况。例如,WPF中的,新的XAML名称范围是由在该XAML生产中定义的任何模板定义和创建的。有关XAML名称范围(为WPF编写但与许多XAML名称范围概念相关)的更多信息,请参阅WPF XAML Namescopes

除了为根元素创建的名称范围外,还为在Xaml生产中定义的任何模板隐式创建了名称范围。这应该不令人意外,因为FrameworkTemplate实现了INameScope,因此DataTemplateControlTemplate也是如此。名称范围也是为Style元素创建的。

您可能注意到了ResourceDictionary也实现INameScope,但它是一个有点边缘情况的:在资源字典对象的名字都没有实际上在任何运行时命名适用范围注册。如果你看看实现,你会看到它的INameScope方法或者抛出一个NotSupportedException,什么都不做,或者返回null。这个设计保持了很好的名字。他们被禁止在任何家长范围内注册,同时使他们可用于有限的目的,如在Binding上使用ElementName参考。重申一遍,资源字典作为名称范围是一个边缘案例,实际上,您不应该思考。

除了上面概述的隐式创建的范围之外,还会为创建的对象实现INameScope的任何对象创建节点的Xaml分析器框架创建新的名称范围。与所有名称范围一样,注册名称在该范围内必须是唯一的;但是,它们可能会与堆栈中其他名称范围内的名称相冲突。

当从Xaml实现一个对象时,XamlObjectWriter通过在堆栈中向上寻找具有名称范围的框架来解析名称,一旦它找到包含所需名称的范围就停止。例如,在评估来自x:Reference指令的延迟引用时,会发生这种情况。

它完全依赖于INameScope接口,检查instance is INameScope
是否依赖boolean属性XamlType.IsNameScope

通常后者,但该标记是通过确定一个类型是否是可分配到XAML INameScope类型,其映射到System.Windows.Markup.INameScope设置。它不检查运行时实例,而是检查相应对象创建节点的XamlType。从概念上来说,检查与typeof(INameScope).IsAssignableFrom(instanceType)类似。

你虽然没有问,我想解决最后一个点完整性的考虑:

当一个物体的名称范围注册?

这发生在两种情况下:

  1. 明确设置在XAML元素的x:Name伪财产;
  2. 您设置了一个属性,如FrameworkElement.Name,其定义为运行时名称属性

类型,如FrameworkElement有自己Name财产,而不是迫使开发商分别指定Namex:Name,他们提供一种方法来CLR属性映射到x:Name。如果您查看FrameworkElement的来源,您将看到[RuntimeNameProperty("Name")]属性。这告诉Xaml基础设施,任何FrameworkElement上的Name属性对应于x:Name,并且设置1应该导致另一个被设置。请注意,运行时名称属性可以具有任何有效的名称;它不需要叫做Name