2014-04-16 63 views
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綁定。

爲了測試,我將基本類型TagObject更改爲FrameworkElement,果然,綁定錯誤消失了,但Value仍然沒有更改。我的理論雖然是現在有效的綁定,TagObject不是可視樹的一部分,因此它沒有繼承它的DataContext

我也嘗試給'TextBlock a name, then specifying it as the元素名稱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); } 
     } 
    } 

} 
+0

BindingException的確切消息是什麼? – Heinzi

+0

請注意,我更新了這個例外的問題,以及我認爲可能是潛在原因的其他信息。 – MarqueIV

回答

0

我重新創建你的樣本代碼中VS2013解決方案並複製您所看到的內容。綁定似乎正好發生,但是 - 它正在吐出那些惱人的錯誤消息。經過一番調查,看起來這是一個已知的錯誤 - 我看到其他人也抱怨過它。綁定工作正常。就我可以告訴別人而言,這個問題是,對於ItemsSources,WPF正在嘗試優化對樣式和數據模板的評估,因爲它組成可視化樹,有時會在實際上可用的綁定之前這樣做元素。在你的情況下,TextBlock已經可用了,並且它有一個綁定值,但是它之前的Tag屬性是在那之前編寫的,因此抱怨丟失了FrameworkElement(稍後不再丟失)。

我不認爲這是來自WPF團隊的令人鼓舞的跡象,因爲這看起來很簡單。正確的代碼不應該發出警告或錯誤。

+0

實際上,'僅限XAML'是指TargetObject上的單個綁定,而不是如何設置ListBox。更新我的問題更清楚。並且您應該能夠在DataTemplate中使用ElementName,前提是該名稱在該模板中定義。這工作正常。我很確定問題在於它不是FrameworkElement,即使它是,它不是可視化樹的一部分,所以可能沒有解決方案。不過謝謝。 – MarqueIV