Ok, finally, I found the problem!
After adding diag:PresentationTraceSources.TraceLevel=High
to binding defs (very useful thing btw, in the absence of normal ol' step-by-step debugging), I saw the following in the output:
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 ''
The problem was in the order of MainWindow initialization!
So at the moment when the binding was constructed, my level 0 property (SomeClassProp
) was not yet initialized, which resulted in binding failing completely (without issuing a normal-level binging warning for some reason).
Long story short - moving SomeClassProp
intitialization before the InitializeComponent()
in MainWindow
constructor did the trick, binding started to work with ElementName
too:
public MainWindow()
{
SomeClassProp = new SomeClass();
InitializeComponent();
}
The answer to question - why it worked using RelativeSource
property - lies in these lines of the output log:
System.Windows.Data Warning: 66 : BindingExpression (hash=28713467): RelativeSource (FindAncestor) requires tree context
System.Windows.Data Warning: 65 : BindingExpression (hash=28713467): Resolve source deferred
Data context initialization with RelativeSource
requires tree context, and is deferred to some point in time after construction of the Window
(by that time SomeClassProperty
was already initialized).