Jcl
Jcl

Reputation: 28272

Bind property of root to value of child element in XAML

I'm not too used to WPF, so this is probably something easy, but I've been struggling with it for a couple hours and can't seem to get how to properly do it.

Say I have a BaseUserControl descending from UserControl with a dependency property Text.

Then in XAML I'm creating a BaseUserControl descendant. I want that property Text to be bound to a control defined in that descendant. Say:

<base:BaseUserControl
         ... all namespaces ...
         xmlns:base="clr-namespace:MyControlsBase"
         x:Class="Test.MyTestControl"
         Text="{Binding ElementName=MyTextBox, Path=Text}"
    <TextBox x:Name="MyTextBox" Text="MyText" />
</base:BaseUserControl>

For some reason, I can't get the MyTextBox to update the Text property on the control itself.

If I add a:

<TextBlock Text="{Binding ElementName=MyTextBox, Path=Text}" />

Anywhere inside the control, the textblock shows the correct TextBox value so the binding definition doesn't seem to be the problem.

I have something else which shows the value of Text in that control... say something like:

<Window>
  <StackPanel>
    <test:MyTestControl x:Name="MyControl" />
    <TextBlock Text="{Binding ElementName=MyControl, Path=Text}" />
  </StackPanel>
</Window>

If I update the Text property on MyControlBase from any other means (codebehind, or whatever), it works, and I see the text changed on the textblock... but it doesn't work seem to update when the TextBox inside itself is updated.

Are there any limitations on binding to properties when you are inheriting a control?

PS: the code is obviously artificial and boilerplated for this question

Note: there is obviously something wrong with the binding on that property, since on the trace window, when creating the control, I get a:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=MyTextBox'. BindingExpression:Path=Text; DataItem=null; target element is 'MyTestControl' (Name=''); target property is 'Text' (type 'String')

But it only happens for the `MyTestControl's property, and not for any other binding to the same property inside the XAML.

Upvotes: 0

Views: 1658

Answers (1)

Eben
Eben

Reputation: 552

I believe the problem is that the MyTextBox hasn't been initialized when the BaseUserControl initializes itself and tries to bind with the Text property of the MyTextBox. At this stage, the MyTextBox doesn't exist, as a result you get the 'System.Windows.Data Error: 4 : Cannot find SOURCE for binding with reference'.

You can bind in code-behind after the InitializeComponent() in the CTOR of your MyTestControl.

public MyTestControl()
{
   InitializeComponent();
   Binding b = new Binding("Text");
   b.Source = MyTextBox;
   SetBinding(TextProperty, b);
}

Upvotes: 2

Related Questions