-1

In my WPF app I have a below resource:

<ResourceDictionary>
    <Style x:Key="OnErrorTextBoxStyle" TargetType="{x:Type TextBox}"> 
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="BorderBrush" Value="Red"/>
                <Setter Property="Validation.ErrorTemplate">
                    <Setter.Value>
                        <ControlTemplate>
                            <StackPanel>
                                <AdornedElementPlaceholder x:Name="placeholder" />
                                <TextBlock FontSize="11" FontStyle="Italic" Foreground="Red"
                               Text="{Binding ElementName=placeholder, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" />
                            </StackPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</ResourceDictionary>

My TextBox:

<TextBox Grid.Column="0"
         Grid.Row="1"                 
         Style="{StaticResource OnErrorTextBoxStyle}"
         Height="30"                                 
         Margin="5,8,8,15">            
    <TextBox.Text>
        <Binding Path="MyPath"
                 UpdateSourceTrigger="PropertyChanged"
                 >
            <Binding.ValidationRules>
                <Rules:PathValidationRule ValidatesOnTargetUpdated="True" />
            </Binding.ValidationRules>
        </Binding>                         
    </TextBox.Text>            
</TextBox>

In the view model my myPath property has below aspect (I only show imporant things here):

public string MyPath
{
    get => myObject.currentPath.LocalPath; // currentPath is an Uri Object

    set
    {
        if (!string.IsNullOrWhiteSpace(value))
        {
           // creates an Uri object using value and Uri.TryCreate
           if (Uri.TryCreate(value, UriKind.Absolute, out Uri newUri))
           {
               myObject.currentPath = newUri;
               OnPropertyChanged();
           }
        }
    }
}

When I try to set MyPath property from the view model I get below error:

Cannot get 'Item[]' value (type 'ValidationError') from 
'(Validation.Errors)' (type 'ReadOnlyObservableCollection`1'). 
BindingExpression:Path=AdornedElement.(0)[0].ErrorContent; 
DataItem='AdornedElementPlaceholder' (Name='placeholder'); target 
element is 'TextBlock' (Name=''); target property is 'Text' (type 
'String') 
ArgumentOutOfRangeException:'System.ArgumentOutOfRangeException: 
Specified argument was out of the range of valid values. Parameter 
name: index'

If I remove the static resource Style="{StaticResource OnErrorTextBoxStyle}" from the TextBox, then all works perfectly. So I guess I am doing something wrong in the static resource but I do not know what.

My TextBox has a validation rule which validates what user is typing in. I am not using any other validation mechanism such as INotifyDataErrorInfo and IDataErrorInfo.

Willy
  • 9,848
  • 22
  • 141
  • 284

1 Answers1

1

Try this binding in the ControlTemplate:

<TextBlock FontSize="11" FontStyle="Italic" Foreground="Red"
           Text="{Binding [0].ErrorContent}" />
                        
mm8
  • 163,881
  • 10
  • 57
  • 88
  • It perfectly works, validation error message is shown under the TextBox but now TextBox border is not getting red. Is it possible to display both, validation error message and TextBox border red at the same time? See my post here: https://stackoverflow.com/questions/71177295/wpf-textbox-not-displaying-validation-error-message – Willy Feb 18 '22 at 17:12