为什么此基本绑定失败并出现异常
本文关键字:异常 失败 绑定 为什么 | 更新日期: 2023-09-27 17:58:27
有人能解释为什么下面代码中TagObject
上的绑定会引发以下绑定异常吗?
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Value; DataItem=null; target element is 'TagObject' (HashCode=37895910); target property is 'Value' (type 'String')
我的怀疑是因为TagObject
本身不是FrameworkElement
的子类,所以它本身没有数据上下文,因此不知道如何解析XAML绑定。
为了测试,我将TagObject
的基本类型更改为FrameworkElement
,果然绑定错误消失了,但Value
仍然没有更改。我的理论是,尽管绑定现在是有效的,但TagObject
不是Visual Tree的一部分,因此它没有继承其DataContext
。
我还尝试过让"TextBlock a name, then specifying it as the
ElementName in the binding, but that again threw a binding exception. In this case, my suspicion is that it can't find the named element because
TagObject"仍然不是可视化树的一部分,即使上面对基类进行了更改。
顺便说一句,我知道一个解决方案是简单地将对象创建隐藏在ValueConverter后面,为我包装它,但我想知道是否有一个仅XAML的解决方案来解决TagObject
上的绑定问题。
这是XAML:
<Window x:Class="Test.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:test="clr-namespace:Test">
<Window.Resources>
<DataTemplate DataType="{x:Type test:DataObject}">
<TextBlock Text="{Binding Value}">
<TextBlock.Tag>
<test:TagObject Value="{Binding Value}" />
</TextBlock.Tag>
</TextBlock>
</DataTemplate>
</Window.Resources>
<ListBox x:Name="MainListBox" BorderThickness="0" />
</Window>
这也不起作用。。。
<TextBlock x:Name="MyTextBlock" Text="Test">
<TextBlock.Tag>
<test:TargetObject Value="{Binding DataContext.Value, ElementName=MyTextBlock}" />
</TextBlock.Tag>
</TextBlock>
这是代码:
using System.Windows;
using System.Collections.ObjectModel;
namespace Test
{
public partial class TestWindow : Window
{
public TestWindow()
{
InitializeComponent();
var sourceItems = new ObservableCollection<DataObject>();
for(int i = 1; i <= 10; i++)
sourceItems.Add(new DataObject() { Value = "Item " + i});
MainListBox.ItemsSource = sourceItems;
}
}
public class DataObject : DependencyObject
{
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value",
typeof(string),
typeof(DataObject),
new UIPropertyMetadata(null));
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
}
public class TagObject : DependencyObject
{
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value",
typeof(string),
typeof(TagObject),
new UIPropertyMetadata(null));
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
}
}
我在VS2013解决方案中重新创建了您的示例代码,并复制了您所看到的内容。绑定似乎进行得很好,但是的,它吐出了那些烦人的错误消息。经过一些研究,这似乎是一个已知的错误——我看到其他人也在抱怨它。装订工作正常。据我从其他人那里了解到的问题是,对于ItemsSources,WPF在构建可视化树时试图优化样式和数据模板的评估,有时在实际元素上的绑定可用之前就这样做了。在您的案例中,TextBlock已经可用,并且它有一个绑定值,但其中的Tag属性是在此之前组成的,因此会抱怨缺少FrameworkElement(稍后不再缺少)。
我不认为这是WPF团队的一个令人鼓舞的迹象,因为这似乎是一个非常简单的场景。正确的代码不应该发出警告或错误。