Setting a DataContext in a UserControl affects bindings in the parent

I have a basic UserControl that sets its DataContext to itself for ease of binding:

 <UserControl x:Class="MyControlLib.ChildControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" DataContext="{Binding RelativeSource={RelativeSource Self}}"> </UserControl> 

This is used in the parent XAML file as follows:

 <UserControl x:Class="MyControlLib.ParentControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ctrl="clr-namespace:MyControlLib"> <ctrl:ChildControl x:Name="ChildName" PropertyOnChild="{Binding PropertyInParentContext}"/> </UserControl> 

For some reason, this gives a binding error, which seems to indicate that the DataContext control of the parent affects the setting of the child control to its own DataContext .

System.Windows.Data error: 40: BindingExpression path error: PropertyInParentContext was not found in the 'object' '' ChildControl '(Name =' ChildName ')'. BindingExpression: Path = PropertyInParentContext; DataItem = 'ChildControl' (Name = 'ChildName'); target element is "ChildControl" (Name = "ChildName"); target - property 'PropertyOnChild' (type 'whatever')

Why is the "PropertyInParentContext" looking in the child control and not in the parent DataContext ?

If i remove

 DataContext="{Binding RelativeSource={RelativeSource Self}} 

from a child control, then everything works as I expected.

Did I miss something obvious here?

+12
data-binding wpf xaml user-controls datacontext
Sep 27 '11 at 15:50
source share
2 answers

The declaration of your control and instance creation basically controls the same object, all the properties specified in the declaration are also set on each instance. Therefore, if the properties were "visible", so to speak:

 <UserControl x:Class="MyControlLib.ParentControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ctrl="clr-namespace:MyControlLib"> <ctrl:ChildControl x:Name="ChildName" DataContext="{Binding RelativeSource={RelativeSource Self}}" PropertyOnChild="{Binding PropertyInParentContext}"/> </UserControl> 

This is why you are not setting the DataContext from UserControls , it overrides the inherited DataContext (and even obfuscates the fact that there is a different context). If you want to bind UserControl properties in your declaration, then name the control and use ElementName or RelativeSource -bindings instead.

+11
Sep 27 '11 at 17:55
source share
— -

Self means UserControl , so when you set the DataContext to Self , you set the DataContext in the UserControl object.

The correct syntax for binding to the DataContext control is {Binding RelativeSource={RelativeSource Self}, Path=DataContext} , however, since the DataContext is inherited by the parent, this binding is absolutely unnecessary in any situation.

Also, if you bind a DataContext to Self.DataContext , you essentially create a loop in which the value binds to itself.

+5
Sep 27 '11 at 16:45
source share



All Articles