wpfdata-bindinguser-controls

WPF Databinding inside <Usercontrol> header not working


I have a problem where if I databind the visibility of my usercontrol inside the definition of my <Usercontrol> I get an error. However, if I copy/paste the exact same binding definition into the base grid of that user control the binding works fine.

Is there some reason I can't bind directly in the <UserControl> definition?

Doesn't Work:

<UserControl
             <...>
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800"
             Visibility="{Binding ControlVisibility, RelativeSource={RelativeSource AncestorType={x:Type local:TaskItemDisplayControl}}}">    
    <Grid x:Name="BaseGrid">

With Error:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='TaskForceSigma.UI.Controls.TaskItemDisplayControl', AncestorLevel='1''. BindingExpression:Path=ControlVisibility; DataItem=null; target element is 'TaskItemDisplayControl' (Name='RootTaskControl'); target property is 'Visibility' (type 'Visibility')

Works(no error):

<UserControl
             <...>
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">    
    <Grid x:Name="BaseGrid"          
          Visibility="{Binding ControlVisibility, RelativeSource={RelativeSource AncestorType={x:Type local:TaskItemDisplayControl}}}">

My best guess is that, when the definition of the <UserControl> is evaluated the relevant binding information is not yet available?

For clarification, this error occurs for both controls added in the designer as well as those instantiated in code.

Also, the code never hits breakpoints inside the ControlVisibility getter UNLESS I add the binding into the BaseGrid element.


Solution

  • A RelativeSource Binding with AncesterType won't work because the target element TaskItemDisplayControl is not its own ancestor.

    Use a Binding with RelativeSource Self instead:

    <UserControl ...
        Visibility="{Binding ControlVisibility, RelativeSource={RelativeSource Self}}">
    

    Besides that, it is uncear why your control would have an additional Visibility property at all.