2009-06-10 2 views
30

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

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

(Примечание.. Я не пытаюсь сделать мастер-деталь или что-либо Оба свойствами являются стандартными свойствами CLR)

Update: проблема заключалась в том, что мой ParentProperty зависит от объекта в XAML времени инициализируется. К сожалению, этот объект был определен позже в файле XAML, чем Binding, поэтому объект был null в то время, когда мой ParentProperty был прочитан Binding. Поскольку переставляя файл XAML бы ввернуть макет, единственное решение, которое я мог думать только о том, чтобы определить Binding в коде-за:

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

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

ответ

22

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

+0

Да, это похоже на причину. ParentProperty доступен только для чтения, но зависит от определенного элемента управления в XAML, который инициализируется. Этот объект определен в файле .xaml ПОСЛЕ привязки, поэтому при вызове ParentProperty он выбрал исключение NullReferenceException. Я не заметил, потому что WPF проглотил его. Я должен был проверить окно вывода! – Qwertie

+0

Теперь у меня есть новая головоломка - как определить объекты в правильном порядке в XAML, не испортив макет. – Qwertie

+0

Или я могу каким-то образом привязать привязку до тех пор, пока окно не будет полностью инициализировано, прежде чем он прочитает свойство? Когда я использую {Binding ElementName = xyz, ...}, он работает, даже если xyz определяется позже в файле XAML. Странно, что мой ParentProperty (который использует элемент xyz) не работает только потому, что xyz определяется позже в файле XAML. – Qwertie

3

Выполняют ли как 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 
    } 
36

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

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

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

+4

+1 для подсказки о FallbackValue :) – Qwertie