在 XAML 中实施全局命名空间

Enforce Global Namespace in XAML

在 XAML 中,可以使用 xmlns 指令导入自定义命名空间:

xmlns:custom="clr-namespace:GreatStuff"

在 C# 中,可以使用

导入该命名空间
using GreatStuff;

此外,可以按如下方式强制执行基于全局(根)命名空间的命名空间评估:

using global::GreatStuff;

如何根据 XAML 中的全局命名空间强制执行评估?


背景:

我面临着这样一个命名空间 global::GreatStuff 的(诚然有点模糊)情况,它包含一个 WPF 控件 class 命名为 ... GreatStuff(即完全限定,即 C# 中的 global::GreatStuff.GreatStuff)。在同一个命名空间中,我想在 WPF window.

中使用该控件

有趣的是,在这个星座中,我无法在 [=78] 的 XAML 文件中对 global::GreatStuff.GreatStuff 类型的任何控件使用 Name/x:Name 属性=]:

The type name 'GreatStuff' does not exist in type 'GreatStuff.GreatStuff'. (CS0426)

请注意,如果我不指定 Name/x:Name 属性,同样的文件可以正常编译!

现在,为什么编译器会假设通过设置 Name/x:Name 属性,我正在尝试访问名为 GreatStuff.GreatStuff.GreatStuff 的内容?

可以通过检查从 window XAML 文件生成的 .g.cs 文件找到答案。在该文件中,XAML 片段

<custom:GreatStuff x:Name="stuff"/>

编译为以下 C# 片段:

internal GreatStuff.GreatStuff stuff;

也就是说,使用完全限定名称,但没有显式全局命名空间标记。

当然,作为命名空间global::GreatStuff中class中的一个字段,所有这些都被包裹在

namespace GreatStuff {

因此,可怜的 C# 编译器只能假设 stuff 应该属于 global::GreatStuff.GreatStuff.GreatStuff 类型。如果在

中,则可以避免这种情况
xmlns:custom="clr-namespace:GreatStuff"

我可以在强制使用全局命名空间的同时强制转换任何提及该命名空间前缀的内容。

由于这个问题之外的原因,更改命名空间 and/or class 名称不是此处的选项。

仅当满足以下所有条件时才会出现此问题:

  1. 您有一个 class 与包含它的命名空间同名。
  2. 在同一命名空间内,您有一个 xaml 文件,其中包含也在该命名空间内声明的对象实例。
  3. 该特定对象实例被赋予名称或 x:Name 属性。

如果您无法修改任何内容以使这些条件中的任何一个为假,那么您正在使用一些非常严格的限制。

据我所知,这是xaml编译器的局限性,您需要联系微软解决。我唯一能想到的另一件事是尝试使用构建 xaml 的自定义构建过程来解决它,允许您编辑生成的文件,然后构建代码。这将需要一些研究来弄清楚如何设置。