2009-06-10 35 views
30

我可以綁定到一個屬性,但不是另一個屬性內的屬性。爲什麼不?例如WPF:如何綁定到嵌套的屬性?

<Window DataContext="{Binding RelativeSource={RelativeSource Self}}"...> 
... 
    <!--Doesn't work--> 
    <TextBox Text="{Binding Path=ParentProperty.ChildProperty,Mode=TwoWay}" 
      Width="30"/> 

(注意:我並不想這樣做主的細節或任何這兩個屬性是標準的CLR屬性)

更新:這個問題是我的ParentProperty在XAML是依賴的對象上初始化。不幸的是,該對象稍後在XAML文件中定義的比綁定,所以當我的ParentProperty被綁定讀取時,該對象爲null。由於重新排列XAML文件會搞砸了佈局,我能想到的唯一的解決辦法是定義在後臺代碼綁定:

<TextBox x:Name="txt" Width="30"/> 

// after calling InitializeComponent() 
txt.SetBinding(TextBox.TextProperty, "ParentProperty.ChildProperty"); 

回答

22

所有我能想到的是,ParentProperty被在Binding後改變已創建,並且不支持更改通知。無論是通過DependencyProperty還是通過實施INotifyPropertyChanged,鏈中的每個財產都必須支持變更通知。

+0

是的,這似乎是原因。 ParentProperty是隻讀的,但它取決於正在初始化的XAML中的某個控件。這個對象是在綁定後的.xaml文件中定義的,所以當調用ParentProperty時,它拋出了NullReferenceException。我沒有注意到,因爲WPF吞下了它。我應該檢查輸出窗口! – Qwertie 2009-06-10 22:53:09

+0

現在我有一個新的難題 - 如何在XAML中以正確的順序定義對象而不會弄亂佈局。 – Qwertie 2009-06-10 22:54:54

3

ParentProperty和你的類都實現INotifyPropertyChanged嗎?

public class ParentProperty : INotifyPropertyChanged 
    { 
     private string m_ChildProperty; 

     public string ChildProperty 
     { 
      get 
      { 
       return this.m_ChildProperty; 
      } 

      set 
      { 
       if (value != this.m_ChildProperty) 
       { 
        this.m_ChildProperty = value; 
        NotifyPropertyChanged("ChildProperty"); 
       } 
      } 
     } 

     #region INotifyPropertyChanged Members 

     #endregion 
    } 

    public partial class TestClass : INotifyPropertyChanged 
    { 
     private ParentProperty m_ParentProperty; 

     public ParentProperty ParentProperty 
     { 
      get 
      { 
       return this.m_ParentProperty; 
      } 

      set 
      { 
       if (value != this.m_ParentProperty) 
       { 
        this.m_ParentProperty = value; 
        NotifyPropertyChanged("ParentProperty"); 
       } 
      } 
     } 
} 
    public TestClass() 

    { 
     InitializeComponent(); 
     DataContext = this; 
     ParentProperty = new ParentProperty(); 
     ParentProperty.ChildProperty = new ChildProperty(); 

     #region INotifyPropertyChanged Members 
     #endregion 
    } 
36

您還可以設置DataContext在XAML TextBox(我不知道這是否是最佳的解決方案,但至少你不必做手工代碼隱藏任何東西,除了實施INotifyPropertyChanged的)。當您TextBox早已DataContext(繼承DataContext)你寫這樣的代碼:

<TextBox 
    DataContext="{Binding Path=ParentProperty}" 
    Text="{Binding Path=ChildProperty, Mode=TwoWay}" 
    Width="30"/> 

要知道,直到你DataContextTextBox尚未準備好Text屬性綁定不會被「建立」 - 你可以添加FallbackValue='error'作爲綁定參數 - 它會像指示器那樣顯示綁定是否正確。