RelativeSource работает с вложенным вложенным свойством, а ElementName-нет.
Проблема с нижеприведенным кодом заключается в следующем: привязка к SomeClassProp.SubTextProp
не работает (свойство source не устанавливается на содержимое текстового поля), в то время как к TextProp
она работает.
XAML:
<Window x:Class="TestWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Name="wMain"
SizeToContent="WidthAndHeight">
<StackPanel>
<TextBox Text="{Binding ElementName=wMain, Path=SomeClassProp.SubTextProp}" Width="120" Height="23" />
<TextBox Text="{Binding ElementName=wMain, Path=TextProp}" Width="120" Height="23" />
</StackPanel>
</Window>
И код:
public partial class MainWindow : Window
{
public SomeClass SomeClassProp { get; set; }
public string TextProp { get; set; }
public MainWindow()
{
InitializeComponent();
SomeClassProp = new SomeClass();
}
}
public class SomeClass
{
public string SubTextProp { get; set; }
}
Не упускаю ли я здесь чего-то очевидного?
Обратите внимание, что мне нужно, чтобы эта привязка работала от цели (текстовое поле) к источнику (свойство класса).
UPDATE: когда я изменяю привязку с ElementName=wMain
на RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}
- обе привязки работают. Таким образом, проблема специфична для ElementName
свойство привязки.
1 ответ:
Ладно, наконец-то я нашел проблему!
После добавления
diag:PresentationTraceSources.TraceLevel=High
к привязке defs (очень полезная вещь кстати, при отсутствии нормальной пошаговой отладки ol), я увидел следующее в выводе:System.Windows.Data Warning: 108 : BindingExpression (hash=54116930): At level 0 - for MainWindow.SomeClassProp found accessor RuntimePropertyInfo(SomeClassProp) System.Windows.Data Warning: 104 : BindingExpression (hash=54116930): Replace item at level 0 with MainWindow (hash=47283970), using accessor RuntimePropertyInfo(SomeClassProp) System.Windows.Data Warning: 101 : BindingExpression (hash=54116930): GetValue at level 0 from MainWindow (hash=47283970) using RuntimePropertyInfo(SomeClassProp): System.Windows.Data Warning: 106 : BindingExpression (hash=54116930): Item at level 1 is null - no accessor System.Windows.Data Warning: 80 : BindingExpression (hash=54116930): TransferValue - got raw value {DependencyProperty.UnsetValue} System.Windows.Data Warning: 88 : BindingExpression (hash=54116930): TransferValue - using fallback/default value '' System.Windows.Data Warning: 89 : BindingExpression (hash=54116930): TransferValue - using final value ''Проблема была в порядке инициализации главного окна!
Таким образом, в момент построения привязки мое свойство level 0 (SomeClassProp
) еще не было инициализировано, что привело к полному отказу привязки (без выдачи привязки нормального уровня предупреждение почему-то).Long story short-moving
SomeClassProp
intitialization перед тем, какInitializeComponent()
вMainWindow
конструктор сделал трюк, привязка начала работать сElementName
тоже:public MainWindow() { SomeClassProp = new SomeClass(); InitializeComponent(); }
Ответ на вопрос-почему он работал с использованием свойства
RelativeSource
- лежит в следующих строках выходного журнала :System.Windows.Data Warning: 66 : BindingExpression (hash=28713467): RelativeSource (FindAncestor) requires tree context System.Windows.Data Warning: 65 : BindingExpression (hash=28713467): Resolve source deferred
Инициализация контекста данных с помощью
RelativeSource
требует контекста дерева и откладывается до некоторого момента времени после построенияWindow
(к тому времениSomeClassProperty
уже был инициализированный).