Enforce Global Namespace in XAML

2019-07-24 12:21发布

In XAML, a custom namespace can be imported with an xmlns directive:

xmlns:custom="clr-namespace:GreatStuff"

In C#, that namespace can be imported with

using GreatStuff;

Moreover, evaluation of that namespace based on the global (root) namespace can be enforced as follows:

using global::GreatStuff;

How can I enforce evaluation based on the global namespace in XAML?


Background:

I am facing the (admittedly slightly obscure) situation that there is such a namespace global::GreatStuff, which contains a WPF control class named ... GreatStuff (i.e. fully qualified, that's global::GreatStuff.GreatStuff in C#). In the same namespace, I want to use that control in a WPF window.

Interestingly, in this constellation, I cannot use the Name/x:Name attribute on any controls of type global::GreatStuff.GreatStuff in my XAML file for the window:

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

Note that the very same file compiles fine if I do not specify a Name/x:Name attribute!

Now, why should the compiler assume that by setting a Name/x:Name attribute, I am trying to access something called GreatStuff.GreatStuff.GreatStuff?

The answer can be found by examining the .g.cs file generated from the window XAML file. In that file, the XAML snippet

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

gets compiled to the following C# snippet:

internal GreatStuff.GreatStuff stuff;

That is, the fully-qualified name is used, but without the explicit global namespace marker.

Of course, as a field in a class in namespace global::GreatStuff, all of this is wrapped in

namespace GreatStuff {

And so, the poor C# compiler cannot help but assume that stuff is supposed to be of a type global::GreatStuff.GreatStuff.GreatStuff. This could be avoided if in

xmlns:custom="clr-namespace:GreatStuff"

I could enforce that any mentions of that namespace prefix could be converted while enforcing the global namespace.

For reasons external to this question, changing the namespace and/or class names is not an option here.

1条回答
闹够了就滚
2楼-- · 2019-07-24 13:04

This issue only occurs when all of the following are true:

  1. You have a class with an identical name as the namespace containing it.
  2. Within that same namespace, you have a xaml file with an instance of an object that is also declared within that namespace.
  3. That specific object instance is given a Name or x:Name attribute.

If you cannot modify anything to make any one of those conditions false, then you are working with some very serious restrictions.

As far as I know, this is a limitation of the xaml compiler, and you will need to contact Microsoft about resolving it. The only other thing I can think of would be to try to work around it with a custom build process that builds xaml, allows you to edit the generated files, then builds the code. That would require some research to figure out how to set up.

查看更多
登录 后发表回答