Применение глобального пространства имен в XAML

В XAML пользовательское пространство имен можно импортировать с помощью директивы xmlns:

xmlns:custom="clr-namespace:GreatStuff"

В C# это пространство имен можно импортировать с помощью

using GreatStuff;

Кроме того, оценка этого пространства имен на основе глобального (корневого) пространства имен может быть реализована следующим образом:

using global::GreatStuff;

Как обеспечить оценку на основе глобального пространства имен в XAML?


Предыстория:

Я сталкиваюсь с (по общему признанию, немного неясной) ситуацией, когда существует такое пространство имен global::GreatStuff, которое содержит класс управления WPF с именем ... GreatStuff (т.е. полностью квалифицированный, это global::GreatStuff.GreatStuff в C#). В том же пространстве имен я хочу использовать этот элемент управления в окне WPF.

Интересно, что в этом созвездии я не могу использовать атрибут Name/x:Name для любых элементов управления типа global::GreatStuff.GreatStuff в моем файле XAML для окна:

Имя типа «GreatStuff» не существует в типе «GreatStuff.GreatStuff». (CS0426)

Обратите внимание, что тот же файл прекрасно компилируется, если я не укажу атрибут Name/x:Name!

Теперь, почему компилятор должен предполагать, что, устанавливая атрибут Name/x:Name, я пытаюсь получить доступ к чему-то под названием GreatStuff.GreatStuff.GreatStuff?

Ответ можно найти, изучив файл .g.cs, сгенерированный из XAML-файла окна. В этом файле фрагмент XAML

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

компилируется в следующий фрагмент C#:

internal GreatStuff.GreatStuff stuff;

То есть используется полное имя, но без явного глобального маркера пространства имен.

Конечно, как поле в классе в пространстве имен global::GreatStuff, все это обернуто в

namespace GreatStuff {

Итак, плохой компилятор C# не может не предположить, что stuff должен иметь тип global::GreatStuff.GreatStuff.GreatStuff. Этого можно было бы избежать, если бы в

xmlns:custom="clr-namespace:GreatStuff"

Я мог бы добиться того, чтобы любые упоминания этого префикса пространства имен могли быть преобразованы при соблюдении глобального пространства имен.

По причинам, не связанным с этим вопросом, изменение пространства имен и/или имен классов здесь недопустимо.


person O. R. Mapper    schedule 02.06.2015    source источник


Ответы (1)


Эта проблема возникает только в том случае, если выполняются все следующие условия:

  1. У вас есть класс с тем же именем, что и пространство имен, содержащее его.
  2. В том же пространстве имен у вас есть файл xaml с экземпляром объекта, который также объявлен в этом пространстве имен.
  3. Этому конкретному экземпляру объекта присваивается атрибут Name или x:Name.

Если вы не можете ничего изменить, чтобы сделать любое из этих условий ложным, то вы работаете с очень серьезными ограничениями.

Насколько я знаю, это ограничение компилятора xaml, и вам нужно будет связаться с Microsoft для его решения. Единственное, что я могу придумать, это попытаться обойти это с помощью пользовательского процесса сборки, который создает xaml, позволяет редактировать сгенерированные файлы, а затем строит код. Это потребует некоторых исследований, чтобы выяснить, как настроить.

person Xavier    schedule 03.06.2015
comment
Как насчет подтипа с другим именем, а затем ссылки на этот подтип в xaml? - person fjch1997; 22.03.2018