2009-06-10 28 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ファイルでBindingよりも定義されていました。そのため、ParentPropertyがBindingによって読み込まれた時点でオブジェクトがnullでした。レイアウトを台無しになりXAMLファイルを再配置するので、私は考えることができる唯一の解決策は、コードビハインドでバインディングを定義することでした:

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

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

答えて

22

私はParentPropertyBinding後に変更されていることであると考えることができますすべての変更通知をサポートしていません。チェーン内のすべてのプロパティは、DependencyPropertyであるかどうかにかかわらず、変更通知をサポートするか、INotifyPropertyChangedを実装する必要があります。

+0

はい、これは理由があると思われます。 ParentPropertyは読み取り専用ですが、XAMLの特定のコントロールが初期化されているかどうかによって異なります。このオブジェクトはバインディング後の.xamlファイルで定義されているため、ParentPropertyが呼び出されるとNullReferenceExceptionがスローされます。私はWPFがそれを飲み込んだので気づかなかった。私は出力ウィンドウをチェックしておくべきだった! – Qwertie

+0

今、私は新しいパズルを持っています - どのようにレイアウトを台無しにすることなくXAMLで正しい順序でオブジェクトを定義する。 – Qwertie

+0

または、プロパティを読み取る前に、ウィンドウが完全に初期化されるまで何らかの方法でバインディングを待機させることはできますか? {Binding ElementName = xyz、...}を使用すると、xyzが後でXAMLファイルで定義されても機能します。私のParentProperty(要素xyzを使用する)はxyzが後でXAMLファイルで定義されるために機能しません。 – Qwertie

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

また、(それが最適解だ場合、私は知らないが、少なくとも、あなたがINotifyPropertyChangedを実装するのを除き、分離コードで手動で何もする必要はありません)XAMLでTextBoxためDataContextを設定することができます。あなたのTextBoxが既にDataContextDataContextを継承)があるときには、このようなコードを記述します。

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

TextBoxのためのあなたのDataContextまで、「確立」されることはありませんTextプロパティにバインディング準備ができていないことに注意してください - あなたはFallbackValue='error'を追加することができますBindingパラメータとして、バインディングがOKかどうかを示すインジケータのようなものになります。

+4

FallbackValueについてのヒントについては+1 – Qwertie

関連する問題