You add a Title dependency property to a UserControl, the caller passes Title="{Binding HeaderText}", and the debugger confirms the value arrived. Yet <TextBlock Text="{Binding Title}"/> inside the control shows nothing.
This is a short summary. The full write-up, with measurements on .NET 10 and every edge case, is here:
Binding to a WPF UserControl's Own Dependency Property from Inside the Control
Why it happens
A binding with only a path resolves against DataContext. Inside the control, DataContext is inherited from the consuming view, so {Binding Title} looks for Title on the caller's view model, not on the control. The Output window reports the view model as the DataItem, which gives it away.
Two cases hide the problem completely: when the view model happens to have its own Title (a wrong value shows, no error), and when DataContext is null (blank, no error).
The fix in one line
Give the inner binding an explicit source:
<TextBlock Text="{Binding Title,
RelativeSource={RelativeSource AncestorType={x:Type local:InfoCard}}}" />
ElementName on a named root works too. If the control references many of its own properties, set DataContext on the inner root panel (not on the UserControl itself) and keep plain {Binding Title} below it.
What to avoid
DataContext = this in the constructor makes the inside work but breaks the caller's binding. It only shows up when the caller passes a binding instead of a literal, so it often survives until the control is reused.
The full article also covers ContextMenu vs. inline Popup, DataTemplate name scopes, and when you need BindsTwoWayByDefault.
A Japanese version is also available.
Top comments (0)