Ulrich Beck
Ulrich Beck

Reputation: 76

How ist the DataContext of a Unsercontrol related to its DependencyProperties?

while working with UserControls having DependencyProperties i realized that it is curcial to consider where to set the DataContext. To picture it ive created a sample application. There are two UserControls, both equal except on where the DataContext is set:

Working UserControl:

<UserControl x:Class="DpropTest.OkUserControl"
         ...>
    <Grid DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=dpropTest:OkUserControl }}">
        <TextBlock Text="{Binding Path=MyDepProp}"></TextBlock>
    </Grid>
</UserControl>

Not working user control:

<UserControl x:Class="DpropTest.NotOkUserControl"
         ...
         DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=dpropTest:NotOkUserControl}}" 
         >
<Grid >
    <TextBlock Text="{Binding Path=MyDepProp}"></TextBlock>
</Grid>

Both UserControls have a DependencyProperty called MyDepProp,

 #region Dependency Property Declaration
    public static readonly DependencyProperty MyDepPropProperty = DependencyProperty.Register(
        "MyDepProp", typeof(string), typeof(NotOkUserControl), new PropertyMetadata(default(string)));

    public string MyDepProp
    {
        get { return (string)GetValue(MyDepPropProperty); }
        set { SetValue(MyDepPropProperty, value); }
    }
    #endregion Dependency Property Declaration

This is how i integrated the UserControls to the mainWindow:

<Grid x:Name="ParentGrid">
    <StackPanel>
        <dpropTest:OkUserControl MyDepProp="{Binding Path=ActualWidth, ElementName=ParentGrid}"/>
        <dpropTest:NotOkUserControl MyDepProp="{Binding Path=ActualWidth, ElementName=ParentGrid}"/>
    </StackPanel>
</Grid>

The running application shows the actualWith for the first UserControlonly only, the second UserControl remains unset as the DP doesnt bind.

There is no error in the output window regarding the second UserControl...

Maybe there is an WPF Pro out there with an brief explanation? Thank you! Uli

Upvotes: 0

Views: 43

Answers (2)

dev hedgehog
dev hedgehog

Reputation: 8791

<UserControl x:Class="DpropTest.NotOkUserControl"
         ...
         DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=dpropTest:OkUserControl }}"

Seems to me you are binding to wrong parent! You are inside NotOkUserControl but you are asking for unreachable AncestorType...

Upvotes: 0

Rob van Daal
Rob van Daal

Reputation: 367

I don't think FindAncestor will start with the element itself, but apart from that: you can either set this on the UserControl:

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

or set this in the constructor of the user control, before the InitializeComponent:

DataContext = this;

As a sidenote: it's often not necessary to bind with the ActualWidth of some ancestor; in this case the width of the stackpanel is the same as the width of its parent grid and the width of the usercontrols is the same as the width of ths stackpanel. So in effect MyDepProp is equal to the ActualWidth of the usercontrol.

Upvotes: 1

Related Questions