首页 > 解决方案 > 如果无法更改它们,如何避免这种由 XAML 引起的命名空间冲突?

问题描述

不幸的是,由于我无法控制的令人沮丧的问题,我不得不使用带有我无法更改的命名空间的组件。由于他们构建它们的方式,它会在生成的代码隐藏中引起冲突。

同样,不幸的是,我无权访问定义这些名称空间的代码,因此无法更改它们。否决这对任何人都没有帮助,尤其是没有理由/解释。此外,我还尝试向业主展示这个问题,解释为什么这是一个非常糟糕的设计,但我被告知出于其他原因,更改它们不是一种选择,所以我不得不寻找解决方法.

这是一个简化的例子来说明这个问题。考虑一个包含两个项目、一个“核心”库和消费应用程序的解决方案:

“核心”库中的项目

**“ConsumingApp”中的项目(参考“核心”)**

碰撞的原因可以分三个步骤来解释:

  1. SomeFeature既是一个命名空间的根,又是另一个命名空间的子
  2. TestControl被定义为在命名空间的根版本中(与库相同),而不是在其中MainWindow
  3. 代码生成最终会将为这些 XAML 元素生成的变量放置在 的命名空间范围内MainWindow,而不是与 XAML 中的实际内容相匹配。

现在,如果这些是非生成代码隐藏中手动定义的变量,则处理起来很容易。通过简单地添加前缀global::,它会“植根”您正在输入的命名空间,从而消除所有歧义。

namespace ConsumingApp.SomeFeature{

    public partial class MainWindow{

        // Note the 'global::' prefix
        global::SomeFeature.Controls.TestControl MainTestControl { get; set; }
    }
}

以上将确保它始终相对于全局SomeFeature命名空间而不是嵌套ConsumerApp.SomeFeature命名空间进行解析。很直接。

但是,从 XAML 解析器自动生成的代码隐藏不包含该global::前缀,因此在生成的代码中,您实际上得到了这个:

namespace ConsumingApp.SomeFeature{

    public partial class MainWindow{

        // Note: without the 'global::' prefix, this resolves to
        // 'ConsumingApp.SomeFeature.Controls.TestControl'
        // which doesn't actually exist, causing the mentioned issue.
        SomeFeature.Controls.TestControl MainTestControl { get; set; }
    }
}

导致此错误:

错误 CS0234 名称空间“ConsumingApp.SomeFeature”中不存在类型或名称空间名称“Controls”(您是否缺少程序集引用?)

如代码注释中所述,这是因为它不是在寻找此类路径...

SomeFeature.Controls.TestControl

而是这个:

ConsumingApp.SomeFeature.Controls.TestControl

这不存在,因此错误。

解决方法是以某种方式让自动生成的代码显式输出,global::但我不知道该怎么做,或者即使可以做到。

我尝试过的事情:

  1. 要求他们改变他们的命名空间! (我输了!)
  2. 在 XAML 导入中显式引用程序集:
  3. 在非生成的代码隐藏中定义别名
  4. 在 XAML 世界中搜索别名(未找到)
  5. 避免命名元素,而是通过其他属性手动搜索控件。(可怕,但这确实有效!)

那么这里有什么办法可以让代码生成器包含“global::”前缀,还是有其他方法可以做到这一点?

标签: c#wpfxamlnamespaces

解决方案


推荐阅读