1

谁能解释为什么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 绑定。

为了测试,我更改了TagObjectto的基本类型,FrameworkElement果然,绑定错误消失了,但Value仍然没有改变。我的理论是,虽然绑定现在有效,TagObject但不是可视树的一部分,因此它没有继承它的DataContext.

我还尝试让“TextBlock a name, then specifying it as theElementName in the binding, but that again threw a binding exception. In this case, my suspicion is that it can't find the named element becauseTagObject”仍然不是可视化树的一部分,即使上面的基类发生了变化。

作为记录,我确实知道一个解决方案是简单地将对象创建隐藏在 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); }
        }
    }

}
4

1 回答 1

0

我在 VS2013 解决方案中重新创建了您的示例代码并复制了您所看到的内容。绑定似乎很好,但是是的 - 它正在吐出那些烦人的错误消息。经过一些研究,这似乎是一个已知的错误——我看到其他人也在抱怨它。绑定工作正常。据我从其他人那里得知,问题在于,对于 ItemsSources,WPF 正在尝试优化样式和数据模板的评估,因为它构成了可视化树,有时在实际绑定可用之前执行此操作元素。在您的情况下, TextBlock 已经可用,并且它具有绑定值,但其中的 Tag 属性是在此之前组合的,因此抱怨缺少 FrameworkElement (稍后,它不再丢失)。

我不认为这是 WPF 团队的一个令人鼓舞的迹象,因为这似乎是一个非常简单的场景。正确的代码不应该发出警告或错误。

于 2014-04-16T10:38:09.527 回答