我正在尝试解决一些经常出现的数据绑定错误,如下所示
System.Windows.Data Error: 40 : BindingExpression path error: 'Active' property not found on 'object' ''FrameViewModel' (HashCode=55649279)'. BindingExpression:Path=Active; DataItem='FrameViewModel' (HashCode=55649279); target element is 'ContentControl' (Name='HeaderBorder'); target property is 'NoTarget' (type 'Object')
我有一个附加的依赖属性Active
public bool Active
{
get
{
return (bool)GetValue(ActiveProperty);
}
set
{
SetValue(ActiveProperty, value);
}
}
public static readonly DependencyProperty ActiveProperty
= DependencyProperty.RegisterAttached("Active", typeof(bool), typeof(Card));
绑定在控件模板的主题文件中设置
<ControlTemplate x:Key="FrameHeader" TargetType="ContentControl">
.....
.....
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Active}" Value="True">
<Setter TargetName="HeaderBackground" Property="Background" Value="{DynamicResource SelectedHeaderBrush}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Active}" Value="False">
<Setter TargetName="HeaderBackground" Property="Background" Value="{DynamicResource HeaderBrush}"/>
</DataTrigger>
</ControlTemplate.Triggers>
控件模板用于内容控件,如此处所示(也可以在错误中看到)
<ControlTemplate x:Key="Card" TargetType="{x:Type Button}">
<ContentControl Template="{DynamicResource FrameTemplate}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentControl Template="{DynamicResource FrameHeader}" Grid.Row="0" x:Name="HeaderBorder" >
<Border Style="{DynamicResource BorderTop}">
<DockPanel>
<ContentPresenter x:Name="UpperLeftContent"
DockPanel.Dock="Left"
Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=icush:Frame},
Converter={StaticResource WatchListLockoutTimerVisibilityConverter},
Path=UpperLeftContent}"
Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=icush:Frame},
Converter={StaticResource WatchListLockoutTimerConverter},
ConverterParameter={StaticResource LockoutTimerRadius},
Path=UpperLeftContent}"
/>
<TextBlock x:Name="Header"
Style="{DynamicResource Header}"
Text="{Binding Path=Title}" />
</DockPanel>
</Border>
</ContentControl>
<ContentControl Template="{DynamicResource FrameBody}" Grid.Row="1" Content="{TemplateBinding Content}"/>
</Grid>
</ContentControl>
</ControlTemplate>
我花了很多时间试图弄清楚DependencyProperty是否缺少任何东西,或者绑定是否设置错误但无济于事。 该应用程序按预期工作,但我试图摆脱这种绑定错误。 如果我在XML中删除绑定但是这不是我正在寻找的解决方案,那么错误就会消失。 绑定可能有问题。
我查看了其他几篇文章,阅读了关于依赖属性和绑定的资料和书籍章节,我找不到任何明显的错误。我甚至使用过snoop,但也没有从中获取任何其他信息。 我看过的一些事情在下面给出
BindingExpression path error: property not found on 'object'
System.Windows.Data Error: 40 : BindingExpression path error: property not found on object
WPF Error 40 BindingExpression path error: property not found on 'object'
http://wpftutorial.net/DependencyProperties.html
http://rachel53461.wordpress.com/2012/07/14/what-is-this-datacontext-you-speak-of/
Is there a way to determine where a WPF Binding is declared/created?
WPF slow performance - many DataItem=null binding warnings
任何可能出错的想法以及我如何摆脱错误?
答案 0 :(得分:6)
WPF绑定错误并不总是最容易读取的内容,而是通过冒号/分号/句点分解,然后向后读取:
这可以理解为:
NoTarget
<ContentControl>
Name="HeaderBorder"
DataContext
)类型为FrameViewModel
"Active"
Active
FrameViewModel
媒体资源
通常我建议您在代码中查找看起来有点像这样的内容:
<ContentControl Name="HeaderBorder" NoTarget="{Binding Active}" />
这将是您的问题所在的错误消息
但是,在你的情况下,问题属性是NoTarget
,这显然是与触发器相关的WPF特有的东西(我一直在学习新东西!)。
Google快速搜索会返回this post,这表示问题是由于未使用正确的语法绑定到附加属性引起的。
尝试使用括号为附加属性编写绑定,例如
<DataTrigger Binding="{Binding Path=(local:Card.Active),...
(我不完全确定这是否有效,因为我认为必须将附加的依赖属性附加到UI对象,并且您将自己的属性附加到Card
对象,这听起来像一个数据对象。但我可能是错的,或者误解了你的代码:))
答案 1 :(得分:0)
所以这里的问题是,对于附加属性,你需要将附加属性括在括号中,这是我的代码中缺少的东西。 在@Rachel指向的link中找到的MSDN post指的是此要求。
我也错过了卡类的名称空间前缀。创建名称空间前缀local
后,我将代码更改为以下
<DataTrigger Binding="{Binding Path=(local:Card.Active)}" Value="True">
<Setter TargetName="HeaderBackground" Property="Background" Value="{DynamicResource SelectedHeaderBrush}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=(local:Card.Active)}" Value="False">
<Setter TargetName="HeaderBackground" Property="Background" Value="{DynamicResource HeaderBrush}"/>
</DataTrigger>
这就是所需要的一切!