【问题标题】:Binding works fine, but intellisense says: Cannot resolve property XXX in data context of type 'object'绑定工作正常,但智能感知说:无法在“对象”类型的数据上下文中解析属性 XXX
【发布时间】:2016-11-07 05:39:33
【问题描述】:

我绑定了一个父元素。如何在绑定中为 DataContext 提供数据类型,以便智能感知可以解析绑定的属性?

绑定在运行时工作正常。所以,我有以下 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”,就像我为内容模板所做的那样,但这也不会改变智能感知警告(我猜是错误的,因为数据元素的类型确实是 TabItem)。

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

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

但这也不能消除警告。

【问题讨论】:

  • VM 是否在设计时为要绑定的项目生成数据?
  • 不,在设计时还没有此 TabControl 的数据。稍后会根据网络通信填充它。
  • 如果您删除按钮的内容,智能感知失败是否仍然发生?目前尚不清楚错误发生在哪里......如果您可以将其缩小到命令或内容,那可能会说明问题。另外,您使用的是哪个版本的 Visual Studio?您是否尝试过最新的 Blend 版本,是否会出现同样的情况?
  • 我使用 VS 15,但我不使用 Blend。

标签: c# wpf data-binding datacontext


【解决方案1】:

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

以下内容来自

内森·亚当 (2010-06-04)。 WPF 4 发布(Kindle 位置 1799-1811)。萨姆斯。 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" ,但对我来说,问题仍然存在,在更改了我在下面的答案中提到的事情之后。
【解决方案2】:

我至少为上述问题找到了解决方案。我在代码隐藏中设置了相关窗口的DataContext。在我的示例中,TabControl 只是继承了 DataContext,它是一个 ConnectionInfosVM。

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

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

似乎智能感知现在能够解析这些引用。但另一方面,我还将DataTemplate 中包含的TextBlock 更改为以下内容:

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

现在这种TabItemDataContext 实际上是一个不同的类型,因为它是TabItem 的支持对象的类型。所以在这种情况下,智能感知无法找到Property 地址。

那么,问题仍然存在,是否有可能在DataTemplate 中定义的绑定中定义DataContext 的类型?

【讨论】:

    猜你喜欢
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 1970-01-01
    • 2021-05-18
    • 2013-12-13
    • 2014-11-17
    • 2020-10-24
    相关资源
    最近更新 更多