Установка времени разработки DataContext в окне дает ошибку компилятора?


203

У меня есть следующий XAML ниже для главного окна в моем приложении WPF, я пытаюсь установить время разработки d:DataContextниже, что я могу успешно сделать для всех моих различных пользовательских элементов управления, но это дает мне эту ошибку, когда я пытаюсь сделать это на окно...

Error 1 The property 'DataContext' must be in the default namespace or in the element namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'. Line 8 Position 9. C:\dev\bplus\PMT\src\UI\MainWindow.xaml 8 9 UI

<Window x:Class="BenchmarkPlus.PMT.UI.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:UI="clr-namespace:BenchmarkPlus.PMT.UI"
    xmlns:Controls="clr-namespace:BenchmarkPlus.PMT.UI.Controls"
    d:DataContext="{d:DesignInstance Type=UI:MainViewModel, IsDesignTimeCreatable=True}"
    Title="MainWindow" Height="1000" Width="1600" Background="#FF7A7C82">

    <Grid>
        <!-- Content Here -->
    </grid>

</Window>

Ответы:


263

Мне нужно было добавить mc:Ignorable="d"атрибут в тег окна. По сути, я узнал что-то новое. d:Префикс пространства имен , что Expression Blend / Визуальный дизайнер Студия признает фактически игнорируются / «закомментирован» реальным компилятором / XAML анализатор!

<Window 
...
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
...
/>

Следующее было взято из

Натан, Адам (2010-06-04). WPF 4 Unleashed (Kindle Locations 1799-1811). Sams. Kindle Edition.

Совместимость разметки

Пространство имен XML совместимости разметки ( http://schemas.openxmlformats.org/markup-compatibility/2006 , обычно используется с mcпрефиксом) содержит атрибут Ignorable, который инструктирует процессорам XAML игнорировать все элементы / атрибуты в указанных пространствах имен, если они не могут быть разрешены к их типам / членам .NET. (Пространство имен также имеет атрибут ProcessContent, который переопределяет Ignorable для определенных типов в игнорируемых пространствах имен.)

Expression Blend использует эту функцию для таких вещей, как добавление свойств времени разработки к содержимому XAML, которые можно игнорировать во время выполнения.

mc:Ignorableможет быть дан список пространств имен, разделенных пробелами, а mc: ProcessContent может быть дан список элементов, разделенных пробелами. Когда XamlXmlReader обнаруживает игнорируемое содержимое, которое не может быть разрешено, он не сообщает о каких-либо узлах для него. Если игнорируемое содержимое может быть разрешено, об этом будет сообщено нормально. Таким образом, потребители не должны делать ничего особенного, чтобы правильно обрабатывать совместимость разметки.


12
Я уже давно бьюсь головой об этом. Имеет смысл, но кажется огромным упущением (объекты данных времени разработки должны поддерживаться без всех этих взломов)
Basic

3
Если вы хотите использовать игнорируемый контекст данных в своем собственном узле вместо атрибута, используйте <d: Window.DataContext />
ChéDon

Отличный совет, выручил меня в странном исключении компилятора. Без mc: ignorable, даже если я установил d: DataContext, компилятор XAML интерпретировал его как попытку установить DataContext и пожаловался на использование неправильного пространства имен xmlns.
Торе Аурстад

19

Вау, какая боль! Будем надеяться, что MS добавит поддержку VS: время разработки для x: Bind.

Мы должны иметь возможность использовать конструктор VS, а также легко переключаться на x: Bind вместо Binding. Вот что я сделал:

  • В моем представлении я добавил свойство для получения моей модели представления. Это имеет смысл, поскольку пути x: Bind относятся к странице (то есть объекту View).

  • На своей странице XAML я добавил следующее <Page ... >в верхней части XAML:

    mc:Ignorable="d" 
    d:DataContext="{d:DesignInstance Type=local:MyView, IsDesignTimeCreatable=False}" 
    DataContext="{x:Bind}"

Таким образом, фактический контекст данных страницы устанавливается на саму страницу из-за {x:Bind}. Это потому, что x:Bindотносится к странице и не указан путь.

В то же время, из-за d:DataContextлинии, конструктор VS размышляет над классом MyView (без создания экземпляра) с целью взаимодействия дизайнера VS. Это позволяет проектировать VS из MyView, где вы можете затем прокрутить вниз до свойства ViewModel, развернуть его и выбрать элемент, с которым вы хотите связать.

Когда вы сделаете все это, конструктор VS создаст оператор Binding, путь которого относительно View, то есть он точно совпадает с путем, ожидаемым x: Bind. Итак, если вы хотите позже переключиться на x: Bind, вы можете просто найти и заменить все " {Binding" на " {x:Bind".

Почему нам даже нужна d:DataContextстрока, чтобы сказать VS, на какой класс смотреть? Хороший вопрос, поскольку вы могли бы подумать, что VS может выяснить, что следующая строка устанавливает DataContext для страницы, используя DataContext={x:Bind}. Попробуйте, это не работает и не работает, если вы измените x: Bind to Binding относительно себя.

Надеюсь, эта ситуация будет исправлена ​​MS!


3
WPF не поддерживает x: Bind; этот ответ не будет работать для ОП.
Бэррел Митчелл
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.