3
votes

My UserControl requires binding to the ancestor (the ancestor being the MainWindow) and to itself (it's code behind).

To bind to the ancestor, I'm using

DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1,AncestorType=Window}}"> 

To bind a control to the code behind (and thus using the 'local' DataContext), I'm using

<TextBlock Text ="{Binding MyUC3Property}" Name="MyName" />

and in the code behind, setting it like

this.MyName.DataContext = this;

The above works fine, where I can bind to the codebehind and to the ancestor.

Now, I still want to bind to the code behind and the ancestor but set the DataContext in the XAML only (if possible).

I've tried

<TextBlock Text ="{Binding MyUC3Property}" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}" /> 

and ensured the constructor does not set the DataContext (since I want it all done in the XAML) - (although even if I do set this.DataContext = this; the error persists)

and the output window tells me there is a binding error.

System.Windows.Data Error: 40 : BindingExpression path error: 'MyUC3Property' property not found on 'object' ''TextBlock' (Name='')'. BindingExpression:Path=MyUC3Property; DataItem='TextBlock' (Name=''); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

I guess I'm missing something obvious, but I can't tell what.

3
What binding error is there? What is the error message?O. R. Mapper
In the constructor of the window / control set this.DataContext = this;RononDex
I presume you renamed MyUC3Property into MyLocalProperty for the sample source code in the question?O. R. Mapper
@RononDex I did try this, but how will it help? It will 'overwrite' that I do want binding to the parent.Dave
@DaveRook Hope this pdf will be helpful to you nbdtech.com/Free/WpfBinding.pdfasitis

3 Answers

9
votes

You should be able to bind to the user control the same way as you do to the window:

DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1,AncestorType=UserControl}}">

What you have tried was referring to the relative source Self from the TextBox. However, in that context, Self refers to the TextBox, not to the enclosing user control.

2
votes

for usercontrols you should never set the datacontext to self. check to comment from H.B. from here

i use ElementName Binding

 <UserControl x:Name="uc">
   <TextBlock Text="{Binding ElementName=uc, Path=MyDependencyPropertyDefinedInMyUserControl}"/>

using the usercontrol:

 <Window>
   <MyUserControl MyDependencyPropertyDefinedInMyUserControl="{Binding Path=MyValueForTheTextBox}"/>

i try to explain it a little bit for your textbox case (ignor my poor english btw :))

if you want create a usercontrol with a textbox and this usercontrol/textbox should show the text from differrent viewmodels in different views - then you have a problem as far as the viewmodels have different propertynames. now the dependency property in your usercontrol come into the game. you create a DP where all your viewmodels can bind to and you bind your textbox within your usercontrol just to the DP from your usercontrol.

0
votes

First thing is that you should probably push your parent DataContext to the lower levels. This will give you "God" ViewMode shared between all nested screens.

Second is that you should probably use something like MVVMLights Messanger to have cleaner separation.