2015-08-29 72 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