I have a user control called "CardDisplay", with an exposed Dependency Property called "CardValue". The control itself is basically just a textblock (an image really, but it works with a textblock and is easier to show) bound to this property, like so:
<UserControl>
<Grid>
<TextBlock Text="{Binding CardValue}"/>
</Grid>
</UserControl>
The data context is set to this
in the code-behind for simplicity, though it works with a standard view model as well. This works fine, if you use it like this:
<local:CardDisplay CardValue="2"/>
"2" appears in the control as expected. However, if I change that line to
<local:CardDisplay CardValue="{Binding CurrentCard}"/>
Nothing is displayed, and I get a binding exception saying that "CurrentCard" could not be found on type "DisplayCard". Obviously it shouldn't be looking at display card, it should be looking at the parent's data context (which of course, has a property called "CurrentCard").
Switching to an "ElementName" binding works as expected:
<TextBock x:Name="HiddenText" Text="{Binding CurrentCard}"/>
<local:CardDisplay CardValue="{Binding Path=Text, ElementName=HiddenText}"/>
Basically, I am at a loss as to why my binding suddenly stops looking in the right spot. The same behavior can be seen in a simple data template as well:
<DataTemplate x:Key="CardTemplate">
<Image Source="{Binding Converter={StaticResource IntToImgSourceConverter}"/>
</DataTemplate>
<ContentPresenter ContentTemplate="{StaticResource CardTemplate}" Content="{Binding CurrentCard}"/>
Will throw a binding exception saying it can't find a property called "CurrentCard" on the "int" type.
Why are the parent-level bindings trying to find properties on the child's data context? Removing the data context from the child fixes (bindings work as expected again), but it seems like that shouldn't be necessary.
EDIT: To be clear, binding the DP is basically useless after setting the data context because of this. If my bindings are correct, what is the best way to get it to use the parent's data context? The use case I am thinking of is getting this to work:
<ItemsControl ItemsSource={Binding PlayerHand}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:CardDisplay CardValue="{Binding Path=CardValue}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This kind of binding :
<local:CardDisplay CardValue="{Binding CurrentCard}"/>
means bind to path CurrentCard
from binding source current DataContext
. Since you're setting DataContext
of UserControl in code-behind it doesn't inherit parent DataContext
, hence binding error you got. DataContext
inherited from parent DataContext
only if you don't set it in child level.
In the other side, this kind of binding works fine :
<local:CardDisplay CardValue="{Binding Path=Text, ElementName=HiddenText}"/>
because this one has nothing to do with current DataContext
. It is explicitly set an element as binding source instead of current DataContext
.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments