wpf 在 Window 上设置设计时 DataContext 会导致编译器错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8303803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:11:54  来源:igfitidea点击:

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

wpf

提问by Jon Erickson

I have the following XAML below for the main window in my WPF application, I am trying to set the design time d:DataContextbelow, 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...

我的 WPF 应用程序的主窗口下面有以下 XAML,我正在尝试设置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

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>

回答by Jon Erickson

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!

我需要将该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"
...
/>

The following was taken from

以下内容来自

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

内森,亚当(2010-06-04)。WPF 4 Unleashed(Kindle 位置 1799-1811)。萨姆斯。Kindle版。

Markup Compatibility

标记兼容性

The markup compatibility XML namespace (http://schemas.openxmlformats.org/markup-compatibility/2006, typically used with an mcprefix) 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.)

标记兼容性 XML 命名空间(http://schemas.openxmlformats.org/markup-compatibility/2006,通常与mc前缀一起使用)包含一个 Ignorable 属性,该属性指示 XAML 处理器忽略指定命名空间中的所有元素/属性,如果它们不能被解析为他们的 .NET 类型/成员。(命名空间还有一个 ProcessContent 属性,该属性覆盖被忽略命名空间内特定类型的 Ignorable。)

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

Expression Blend 利用此功能执行一些操作,例如将设计时属性添加到 XAML 内容中,这些属性在运行时可以忽略。

mc:Ignorablecan 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.

mc:Ignorable可以给定一个以空格分隔的命名空间列表,并且可以给 mc:ProcessContent 一个以空格分隔的元素列表。当 XamlXmlReader 遇到无法解析的可忽略内容时,它不会为其报告任何节点。如果可以解决可忽略的内容,则正常上报。所以消费者不需要做任何特殊的事情来正确处理标记兼容性。

回答by sjb --

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

哇,好痛!让我们希望 MS 为 x:Bind 提供一些 VS 设计时支持。

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:

我们能够使用 VS 设计器,但也能够轻松切换到 x:Bind 而不是 Binding。这是我所做的:

  • 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}"
    
  • 在我的视图中,我添加了一个属性来获取我的 ViewModel。这是有道理的,因为 x:Bind 路径是相对于 Page(即 View 对象)。

  • 在我的页面 XAML 中,我将以下内容添加到<Page ... >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:Bindis relative to the Page and there is no path given.

这样,由于{x:Bind}. 那是因为x:Bind相对于页面并且没有给出路径。

At the same time, due to the d:DataContextline, 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.

同时,由于d:DataContext线路的原因,VS设计器出于VS设计器交互的目的而在MyView类上进行反思(没有创建实例)。这让 VS 可以从 MyView 进行设计,然后您可以向下滚动到 ViewModel 属性,将其展开并选择要绑定到的项目。

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".

当您完成所有这些操作时,VS 设计器将创建一个 Binding 语句,其路径是相对于视图的,即它恰好与 x:Bind 期望的路径完全相同。所以,如果你想稍后切换到 x:Bind,你可以搜索并用“ {Binding”替换所有的“ {x:Bind”。

Why do we even need the d:DataContextline 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.

为什么我们甚至需要d:DataContext一行来告诉 VS 看什么类?好问题,因为您会认为 VS 可以找出下一行将 DataContext 设置为页面,使用DataContext={x:Bind}. 继续尝试它,它不起作用,如果您将 x:Bind 更改为相对于 self 的 Binding,它也不起作用。

Hopefully this situation will get cleaned up by MS !!

希望这种情况会被 MS 清理掉!!