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

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

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>

Ответ 1

Мне нужно было добавить атрибут mc:Ignorable="d" к тегу Window. По сути, я узнал что-то новое. Префикс пространства d:, который выражает разработчик Expression Blend/Visual Studio, фактически игнорируется/ "закомментирован" реальным компилятором/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 сталкивается с незнакомым контентом, который не может быть разрешен, он не сообщает о каких-либо узлах для него. Если игнорировать контент можно, он будет сообщаться в обычном режиме. Поэтому потребителям не нужно делать что-либо особенное для правильной работы с совместимостью разметки.

Ответ 2

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

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

  • В моем представлении я добавил свойство, чтобы получить свой ViewModel. Это имеет смысл, потому что x: Связывает пути относительно страницы (т.е. Объект 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, путь которого относится к представлению, то есть он будет точно таким же, как и путь, который x: Bind ожидает. Итак, если вы хотите переключиться на x: Bind позже, вы можете просто найти и заменить все "{Binding" на "{x:Bind".

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

Надеюсь, эта ситуация будет очищена MS!!