Search code examples
c#wpfvalidationxamldatatemplate

Custom validation error template not respecting ZIndex


I have a view defined as a DataTemplate (for an "OrderEntryViewModel") with a Menu, ContentPresenter, and Expander inside of a 3-row grid. The content of the ContentPresenter is binded to another viewModel "OrderViewModel" (for which there's another DataTemplate-defined view). The expander has a ZIndex of 99, so that when it expands UP, it expands OVER any other controls (i.e. the ContentPresenter).

This all works as expected EXCEPT when the ContentPresenter's content (the OrderViewModel) has data errors...My OrderView displays a custom validation error template around controls with invalid data. What happens is, when I expand the expander, all of controls inside the ContentPresenter are covered, but the red border and exclamation point I show are still visible through the expander! I've verified that my expander's ZIndex is 99 and the ContentPresenter's is 0. Can anyone help me with this?

Here's some images to help explain:

First Image shows what the views look like when NOT expanded.

Second Image shows what the views look like when I expand.

I define the validation error template like this:

<ControlTemplate x:Key="ValidationErrorTemplate">
    <DockPanel LastChildFill="true">
        <Border Background="Red" DockPanel.Dock="right" Margin="5,0,0,0" Width="10" Height="10" CornerRadius="5" 
                ToolTip="{Binding AdornedElement.(Validation.Errors).CurrentItem.ErrorContent, ElementName=customAdorner}">
            <TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center" FontWeight="Bold" Foreground="White"/>
        </Border>
        <AdornedElementPlaceholder x:Name="customAdorner" VerticalAlignment="Center">
            <Border BorderBrush="red" BorderThickness="1" />
        </AdornedElementPlaceholder>
    </DockPanel>
</ControlTemplate>

And assign it to a specific control like this (this is how I do it for my TextBox):

<Style TargetType="{x:Type TextBox}" x:Key="ValidatedStyleTextBox">
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsLocked}" Value="True">
            <Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding IsLocked}" Value="False">
            <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ValidationErrorTemplate}"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

Solution

  • This solution worked for me...just added an AdornerDecorator at the same level as my expander, so now, the controls inside of the AdornerDecorator use that layer to display instead of the top level layer in the window