WPF: How to bind to a nested property?

61,211

Solution 1

All I can think of is that the ParentProperty is being changed after the Binding is created, and it does not support change notification. Every property in the chain must support change notification, whether it be by virtue of being a DependencyProperty, or by implementing INotifyPropertyChanged.

Solution 2

You can also set DataContext for TextBox in XAML (I don't know if it's optimal solution, but at least you don't have to do anything manually in codeBehind except of implementing INotifyPropertyChanged). When your TextBox has already DataContext (inherited DataContext) you write code like this:

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

Be aware that until your DataContext for TextBox isn't ready binding for Text property will not be 'established' - you can add FallbackValue='error' as Binding parameter - it will be something like indicator which will show you if binding is OK or not.

Solution 3

Do both the ParentProperty and your class implement 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
    }
Share:
61,211
Qwertie
Author by

Qwertie

Updated on November 09, 2021

Comments

  • Qwertie
    Qwertie over 2 years

    I can bind to a property, but not a property within another property. Why not? e.g.

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

    (Note: I'm not trying to do master-details or anything. Both properties are standard CLR properties.)

    Update: the problem was that my ParentProperty depended on an object in XAML being initialized. Unfortunately that object was defined later in the XAML file than the Binding, so the object was null at the time when my ParentProperty was read by the Binding. Since rearranging the XAML file would screw up the layout, the only solution I could think of was to define the Binding in code-behind:

    <TextBox x:Name="txt" Width="30"/>
    
    // after calling InitializeComponent()
    txt.SetBinding(TextBox.TextProperty, "ParentProperty.ChildProperty");