4
votes

I have an ItemsControl (let's say a ListBox) and I have a DataTemplate for the contents. When I press a button, I want all ListBoxItems to be validated. This works.

Yet, although all items are properly validated and I can retrieve error messages for them, WPF does only show the ValidationError.Template for the SelectedItem of the ListBox in question. It does not display the ValidationError.Template for the other items which failed validation. I do update the source of the binding for every item and the Validation.HasError Property is set to true for them! Just the visuals are missing, the style is not being applied!

Has anyone got a solution for the problem?

Sample

A TextBox Style:

<Style TargetType="{x:Type TextBox}">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <DockPanel LastChildFill="True">
                        <AdornedElementPlaceholder Name="MyAdorner" />
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

    <Setter Property="Background" Value="{DynamicResource TextBoxBackgroundBrush}" />
    <Style.Triggers>
        <Trigger Property="IsFocused" Value="true">
            <Setter Property="Background" Value="{DynamicResource TextBoxFocusBackgroundBrush}" />
        </Trigger>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="Background" Value="{DynamicResource ErrorBrush}" />
            <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
        </Trigger>
    </Style.Triggers>

</Style>

A DataTemplate for a Person Entity:

<DataTemplate DataType="{x:Type entities:Person}" x:Key="PersonItemStyle">
    <Grid>
        <TextBox x:Name="SomeTextBox">
            <TextBox.Text>
               <Binding Path="Name" UpdateSourceTrigger="PropertyChanged">
                   <Binding.ValidationRules>
                            <validators:RequiredFieldValidationRule ErrorMessage="Please enter a name!" />
                   </Binding.ValidationRules/>
               </Binding>
            </TextBox.Text>
        </TextBox>
    </Grid>
</DataTemplate>

Somewhere in some control:

        <ListBox Grid.Row="1" x:Name="ListBoxPersons" Style="{DynamicResource ListBoxStyle}" ItemsSource="{Binding Path=Persons}" 
ItemContainerStyle="{StaticResource PersonItemStyle}">
        </ListBox>

Then try editing a few persons, for example set their names to null or use any erroneous binding. When you validate, the triggers for Validation.HasError will only be set for the selected item.

How can one work around that problem?

1

1 Answers

0
votes

You are setting the ItemContainerStyle to a DataTemplate, why? The style is applied to all textboxes so you shouldn't have to set the ItemContainerStyle separately.