代码之家  ›  专栏  ›  技术社区  ›  Qwertie

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

  •  33
  • Qwertie  · 技术社区  · 16 年前

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

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

    (注:我不想做细节或任何事情。这两个属性都是标准的CLR属性。)

    更新:问题是ParentProperty依赖于正在初始化的XAML中的对象。不幸的是,该对象在XAML文件中的定义比绑定晚,因此在绑定读取ParentProperty时,该对象为空。因为重新排列XAML文件会破坏布局,所以我能想到的唯一解决方案是在代码后面定义绑定:

    <TextBox x:Name="txt" Width="30"/>
    
    // after calling InitializeComponent()
    txt.SetBinding(TextBox.TextProperty, "ParentProperty.ChildProperty");
    
    3 回复  |  直到 13 年前
        1
  •  23
  •   Tim Cooper    14 年前

    我能想到的就是 ParentProperty Binding 已创建,不支持更改通知。链中的每个属性都必须支持更改通知,无论它是通过 DependencyProperty 或通过实施 INotifyPropertyChanged .

        2
  •  40
  •   Michał Powaga Mohamed Aslam    13 年前

    你也可以设置 DataContext 对于 TextBox 在XAML中(我不知道它是否是最佳解决方案,但至少在codebehind中,除了实现 INotifyPropertyChanged )当你 文本框 已经 数据上下文 (遗传的 数据上下文 )您编写的代码如下:

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

    注意直到你 数据上下文 对于 文本框 尚未准备好绑定 Text 属性将不会“建立”-您可以添加 FallbackValue='error' 作为绑定参数-它类似于指示器,指示绑定是否正常。

        3
  •  4
  •   user112889    16 年前

    ParentProperty和类都实现了InotifyPropertiesChanged吗?

        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
        }