web-dev-qa-db-ja.com

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が読み取られた時点でオブジェクトはnullでした。 XAMLファイルを再配置するとレイアウトが台無しになるため、考えられる唯一の解決策は、コードビハインドでバインディングを定義することでした。

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

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

私が考えることができるのは、ParentPropertyが作成された後にBindingが変更されており、変更通知をサポートしていないということだけです。 DependencyPropertyであるか、INotifyPropertyChangedを実装するかによって、チェーン内のすべてのプロパティは変更通知をサポートする必要があります。

23
Kent Boogaart

XAMLのDataContextTextBoxを設定することもできます(最適な解決策かどうかはわかりませんが、少なくともINotifyPropertyChanged)。 TextBoxがすでにDataContext(継承されたDataContext)を持っている場合、次のようなコードを記述します。

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

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

44
ilektrik

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
    }
4
user112889