绑定正常,但是智能感知显示:无法解析'type为'object'的数据上下文中的XXX属性。

10

我有一个与父元素绑定的绑定。我如何为绑定中的DataContext提供数据类型,以便Intellisense可以解析绑定的属性?

在运行时,绑定正常工作。因此,我有以下XAML结构:

<TabControl Name="TabDynamic" 
            ItemsSource="{Binding TabItems, Mode=OneWay}" ...>
    <TabControl.Resources>
        <DataTemplate x:Key="TabHeader" DataType="TabItem">
            <DockPanel>
                <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Header}" />
                <Button Command="{Binding ElementName=TabDynamic, Path=DataContext.DeleteTabCommand}"
                        CommandParameter="{Binding ElementName=TabDynamic, Path=DataContext.TabItems/}">
                    <Image Source="{DynamicResource DeleteImg}" Height="11" Width="11"></Image>
                </Button>
            </DockPanel>
        </DataTemplate>
        <DataTemplate x:Key="TabContent" DataType="viewModels:ConnectionInfoVM">
            <views:BufferViewerControl/>
        </DataTemplate>
    </TabControl.Resources>
</TabControl>

DataContext 的数据类型是 "viewModels:ConnectionInfoVM"。 Intellisense 现在会在 DataContext 上同时下划线显示两个属性(即 DeleteTabCommand 和 TabItems)。

我已经尝试在 Button 元素中使用设计时数据上下文定义 "d:DataContext",如下所示:

d:DataContext="{d:DesignInstance viewModels:ConnectionInfosVM}"

但这并不会改变智能感知警告。

我还尝试将DataTemplate上的DataType定义为"viewModels:ConnectionInfosVM",就像我对content-template所做的那样,但是这也不能改变智能感知警告(而且我想这可能是错误的,因为元素的数据类型确实是TabItem)。

另一个尝试是通过在Button元素定义中添加以下内容来定义DataContext:

<Button.DataContext>
    <viewModels:ConnectionInfosVM/>
</Button.DataContext>

但是这也不能消除警告。


虚拟机在设计时是否生成要绑定的项目的数据? - ΩmegaMan
不,设计时还没有这个TabControl的数据。它会在后面根据网络通信进行填充。 - ptair
如果您删除按钮的内容,智能感知是否仍然失败?不清楚错误发生在哪里...如果您可以将其缩小到命令或内容中的任一项,那可能会有所提示。另外,您使用的是哪个版本的Visual Studio?您是否尝试过最新的Blend版本,是否发生相同的情况? - ΩmegaMan
我使用VS 15,但我不使用Blend。 - ptair
2个回答

2

我需要将mc:Ignorable="d"属性添加到Window标签中。实际上,我学到了一些新的东西。Expression Blend/Visual Studio设计师认可的d:命名空间前缀实际上被真正的编译器/xaml解析器忽略/"注释掉"!

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

以下内容摘自:

Nathan,Adam(2010-06-04)。WPF 4 Unleashed(Kindle位置1799-1811)。Sams。Kindle版。

标记兼容性

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

Expression Blend利用此功能执行诸如向可以在运行时忽略的XAML内容添加设计时属性之类的操作。

mc:Ignorable可以给出一个以空格分隔的命名空间列表,mc:ProcessContent可以给出一个以空格分隔的元素列表。当XamlXmlReader遇到无法解析的可忽略内容时,它不会报告任何节点。如果可忽略内容可以解析,则会正常报告。因此,消费者无需采取任何特殊措施即可正确处理标记兼容性。


我实际上已经设置了mc:Ignorable="d",但对我来说,问题仍然存在,即使在我下面的答案中更改了提到的事情。 - ptair

2

我至少找到了一个解决以上问题的方法。我在代码后端设置了窗口的DataContext。在我的例子中,TabControl只是继承了该DataContext,它是一个ConnectionInfosVM。

为了修复这些警告(当然也为了通过定位器提供DataContext所获得的灵活性),我在XAML中定义了DataContext,如下所示:

<UserControl ...
             DataContext="{Binding Source={StaticResource mainViewModelLocator}, Path=ConnectionInfosVM}">

看起来Intellisense现在能够解决这些引用了。但另一方面,我还将DataTemplate中包含的TextBlock更改为以下内容:

 <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=DataContext.Address}" />

现在,这样一个TabItemDataContext实际上是不同类型的,因为它是TabItem的后备对象的类型。所以在这种情况下,Property地址无法被智能感知找到。
那么问题还存在,有没有可能在DataTemplate中定义绑定的DataContext类型?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接