WPF: как привязать к вложенному свойству?
Я могу привязать свойство, но не свойство в другом свойстве. Почему нет? например.
<Window DataContext="{Binding RelativeSource={RelativeSource Self}}"...>
...
<!--Doesn't work-->
<TextBox Text="{Binding Path=ParentProperty.ChildProperty,Mode=TwoWay}"
Width="30"/>
(Примечание: я не пытаюсь выполнять мастер-данные или что-то еще. Оба свойства являются стандартными свойствами CLR.)
Обновление: проблема заключалась в том, что мой ParentProperty зависел от того, что объект в XAML инициализируется. К сожалению, этот объект был определен позже в файле XAML, чем Binding, поэтому объект был null в то время, когда мой ParentProperty был прочитан Binding. Поскольку перестройка файла XAML испортила бы макет, единственным решением, о котором я мог думать, было определение привязки в коде:
<TextBox x:Name="txt" Width="30"/>
// after calling InitializeComponent()
txt.SetBinding(TextBox.TextProperty, "ParentProperty.ChildProperty");
Ответы
Ответ 1
Все, что я могу представить, это то, что ParentProperty
изменяется после создания Binding
и не поддерживает уведомление об изменении. Каждое свойство в цепочке должно поддерживать уведомление об изменении, независимо от того, является ли оно DependencyProperty
или реализовано INotifyPropertyChanged
.
Ответ 2
Вы также можете установить 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'
как параметр привязки - это будет что-то вроде индикатора, который будет покажите, если привязка в порядке или нет.
Ответ 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
}