WPF: как привязать к вложенному свойству? - PullRequest
34 голосов
/ 11 июня 2009

Я могу связать собственность, но не собственность в другой собственности. Почему бы и нет? например,

<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. Поскольку перестановка файла XAML привела бы к нарушению компоновки, единственное решение, о котором я мог подумать, - это определить Binding в коде:

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

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

Ответы [ 3 ]

44 голосов
/ 06 июня 2011

Вы также можете установить DataContext для TextBox в XAML (я не знаю, является ли это оптимальным решением, но, по крайней мере, вам не нужно ничего делать вручную в codeBehind, кроме реализации INotifyPropertyChanged). Когда у вашего TextBox уже есть DataContext (унаследовано DataContext), вы пишете такой код:

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

Имейте в виду, что до тех пор, пока ваше DataContext для TextBox не будет готово, привязка для свойства Text не будет 'установлена' - вы можете добавить FallbackValue='error' в качестве параметра Binding - это будет что-то вроде индикатора, который будет покажет вам, если привязка в порядке или нет.

23 голосов
/ 11 июня 2009

Все, что я могу думать, это то, что ParentProperty изменяется после создания Binding, и оно не поддерживает уведомление об изменении. Каждое свойство в цепочке должно поддерживать уведомление об изменении, будь то в силу того, что оно является DependencyProperty, или путем реализации INotifyPropertyChanged.

4 голосов
/ 11 июня 2009

И 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
    }
...