take a look at this Xaml:

<Grid>
    <behaviors:Overlay.Content>
        <TextBlock Text="Logon failed, please check your username and password."
                   Foreground="Red" FontWeight="Bold" FontSize="30" />
    </behaviors:Overlay.Content>
</Grid>

it utilizes a feature built-in in Radical: overlay adorners, that under the hood utilize a WPF Adorner and AdornerLayer to host the given content on top, as a layer, of the adorned element, in this sample a Grid.

Now, everything works fine and you can use all the WPF features inside an adorner, such as data binding:

<Grid>
    <behaviors:Overlay.Content>
        <TextBlock Text="{Binding Path=ErrorMessage}"
                   Visibility="{Binding Path=IsErrorMessageVisible, Converter={StaticResource boolToVisibilityConverter}}"
                   Foreground="Red" FontWeight="Bold" FontSize="30" />
    </behaviors:Overlay.Content>
</Grid>

but the fanny thing is that if everything (in this case the Grid element) is hosted inside template (e.g. a DataTemplate)  bindings tend to fail at runtime…

Take a look at this more detailed sample Xaml:

<Window DataContext="{Binding Path=Source}">
    <Grid>
        <ContentControl Content="{Binding Path=ChildOfSource}">
            <ContentControl.ContentTemplate>
                <DataTemplate>
                    <behaviors:Overlay.Content>
                        <TextBlock Text="{Binding Path=ErrorMessage}"
                                   Visibility="{Binding Path=IsErrorMessageVisible, Converter={StaticResource boolToVisibilityConverter}}"
                                   Foreground="Red" FontWeight="Bold" FontSize="30" />
                    </behaviors:Overlay.Content>
                </DataTemplate>
            </ContentControl.ContentTemplate>
        </ContentControl>
    </Grid>
</Window>

in this case the expected behavior is that ErrorMessage and IsErrorMessageVisible properties can be found on the object identified by the ChildOfSource property exposed, and bound as the Content of the ContentControl, by the Source element bound as the DataContext of the root Window.

It does not work, period. The data binding engine looks for the 2 bound properties on the object identified by the Source property bound on the Window element…why?

The problem is that the adorner content, the TextBlock in this sample, is a child (in term of visual tree) of the Adorner element but the adorner element is not child of the adorned element but is child of the first AdornerLayer found in the logical tree…and in the sample above the first AdornerLayer that can be found is the implicit one, always created by WPF, child of the root Window, thus our TextBlock is a visual child of the Window and not of the Grid and this explains why the data binding engine looks for properties in a place we think is the wrong place.

The solution is fairly simple:

  1. directly bind the DataContext of the elements in the template using the element name of the outer control;
  2. explicitly wraps the content of the DataTemplate within an AdornerLayer;

.m