Setting design time DataContext on a Window is giving a compiler error?
Asked Answered
B

4

235

I have the following XAML below for the main window in my WPF application, I am trying to set the design time d:DataContext below, which I can successfully do for all my various UserControls, but it gives me this error when I try to do it on the window...

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>
Bristling answered 28/11, 2011 at 23:20 Comment(0)
B
316

I needed to add the mc:Ignorable="d" attribute to the Window tag. Essentially I learned something new. The d: namespace prefix that Expression Blend/Visual Studio designer acknowledges is actually ignored/"commented out" by the real compiler/xaml parser!

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

The following was taken from

Nathan, Adam (2010-06-04). WPF 4 Unleashed (Kindle Locations 1799-1811). Sams. Kindle Edition.

Markup Compatibility

The markup compatibility XML namespace (http://schemas.openxmlformats.org/markup-compatibility/2006, typically used with an mc prefix) contains an Ignorable attribute that instructs XAML processors to ignore all elements/attributes in specified namespaces if they can’t be resolved to their .NET types/members. (The namespace also has a ProcessContent attribute that overrides Ignorable for specific types inside the ignored namespaces.)

Expression Blend takes advantage of this feature to do things like add design-time properties to XAML content that can be ignored at runtime.

mc:Ignorable can be given a space-delimited list of namespaces, and mc:ProcessContent can be given a space-delimited list of elements. When XamlXmlReader encounters ignorable content that can’t be resolved, it doesn’t report any nodes for it. If the ignorable content can be resolved, it will be reported normally. So consumers don’t need to do anything special to handle markup compatibility correctly.

Bristling answered 28/11, 2011 at 23:43 Comment(4)
I've been beating my head against this for quite some time. Makes sense but seems like a huge oversight (design-time data objects should be supported without all these hacks)Bessiebessy
If you want ignorable data context in its own node instead as an attribute use <d:Window.DataContext />Octavus
Great tip, helped me out striving with a strange compiler exception. Without mc:ignorable, even if I set d:DataContext, the XAML compiler interpreted it as trying to set DataContext and complained about using the wrong xmlns namespace.Wooster
This actually didn't clear up for me until I put the mc:Ignorable="d" line on the line below the d:DataContext=... line, for whatever reason. Yet in another file I didn't have to do that. Using VS2022.Fiddler
A
28

Wow, what a pain! Let's hope MS puts in some VS design-time support for x:Bind.

We to be able to use the VS designer but also be able to switch easily to x:Bind instead of Binding. Here's what I did:

  • In my View, I added a property to get my ViewModel. This makes sense because x:Bind paths are relative to the Page (i.e. the View object).

  • In my Page XAML, I added the following to the <Page ... > at the top of the XAML:

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

This way, the Page's actual data context is set to the Page itself due to the {x:Bind}. That's because x:Bind is relative to the Page and there is no path given.

At the same time, due to the d:DataContext line, the VS designer reflects on the MyView class (without creating an instance) for the purpose of the VS designer interaction. This lets VS design from MyView, where you can then scroll down to the ViewModel property, expand it and select the item that you want to bind to.

When you do all that, the VS designer will create a Binding statement whose path is relative to the View, i.e. it happens to be exactly the same as the path that x:Bind expects. So, if you want to switch to x:Bind later on, you can just search and replace all "{Binding" with "{x:Bind".

Why do we even need the d:DataContext line to tell VS what class to look at? Good question, since you would think that VS could figure out the very next line sets the DataContext to the Page, using DataContext={x:Bind}. Go ahead and try it, it does not work and neither does it work if you change x:Bind to Binding relative to self.

Hopefully this situation will get cleaned up by MS !!

Actinolite answered 10/3, 2016 at 5:52 Comment(1)
WPF doesn't support x:Bind; this answer won't work for OP.Guilder
B
1

If you are not tooo fussy on the data have a look at the sample data found in xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

You use it like this...

<ItemsControl ItemsSource="{Binding Path=Report.Audit.Data}" d:ItemsSource="{d:SampleData}" Grid.Row="1">
<ItemsControl.ItemTemplate>
 <DataTemplate>
 </DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

it then renders the items control with a few rows of data

Botticelli answered 14/7, 2021 at 10:55 Comment(0)
H
0

I've solved the problem adding d:DataContext="{d:SampleData}" in the component definition (UserControl or Window).

<UserControl x:Class="TestControl"
             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:local="clr-namespace:TestApp.Views"
             DataContext="{Binding TestViewModel}"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800"
             d:DataContext="{d:SampleData}"
             >
Herta answered 17/2, 2022 at 15:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.