WPF:如何绑定到嵌套属性?

时间:2009-06-10 22:36:24

标签: wpf binding properties nested

我可以绑定到属性,但不能绑定到另一个属性中的属性。为什么不? e.g。

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

(注意:我不是要做master-details或者其他任何东西。这两个属性都是标准的CLR属性。)

更新:问题是我的ParentProperty依赖于XAML中的对象被初始化。不幸的是,该对象后来在XAML文件中定义而不是Binding,因此当Binding读取ParentProperty时,该对象为null。由于重新排列XAML文件会使布局搞砸,我能想到的唯一解决方案是在代码隐藏中定义绑定:

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

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

3 个答案:

答案 0 :(得分:42)

您还可以在XAML中为DataContext设置TextBox(我不知道它是否是最佳解决方案,但至少您不必在codeBehind中手动执行任何操作,除了实现{{ 1}})。当您的INotifyPropertyChanged已经TextBox(继承DataContext)时,您可以编写如下代码:

DataContext

请注意,在<TextBox DataContext="{Binding Path=ParentProperty}" Text="{Binding Path=ChildProperty, Mode=TwoWay}" Width="30"/> DataContext TextBox未准备好对Text属性进行绑定之前,不会“建立” - 您可以添加FallbackValue='error'作为Binding参数 - 它会像指示器一样显示绑定是否正常。

答案 1 :(得分:23)

我能想到的是ParentPropertyBinding创建后发生变化,并且不支持变更通知。链中的每个财产都必须支持变更通知,无论是DependencyProperty还是实施INotifyPropertyChanged

答案 2 :(得分:4)

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
    }