16

I am using the following template for validation error:

<ControlTemplate>
    <Border BorderBrush="Red" BorderThickness="1">
        <Grid>
            <Polygon Points="8,8 8,0 0,0"
                     Stroke="Black"
                     StrokeThickness="1"
                     Fill="Red"
                     HorizontalAlignment="Right"
                     VerticalAlignment="Top"
                     ToolTip="{Binding ElementName=adorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" />
            <AdornedElementPlaceholder x:Name="adorner"/>
        </Grid>
    </Border>
</ControlTemplate>

ToolTip is working fine, but after leaving the current record the following exception is thrown:

System.Windows.Data Error: 17 : Cannot get 'Item[]' value (type 'ValidationError') from '(Validation.Errors)' (type 'ReadOnlyObservableCollection`1'). BindingExpression:Path=AdornedElement.(0)[0].ErrorContent; DataItem='AdornedElementPlaceholder' (Name='adorner'); target element is 'Polygon' (Name=''); target property is 'ToolTip' (type 'Object') ArgumentOutOfRangeException:'System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.

I tried with HasError property, but failed. Anyone has any idea?

Lorenz Lo Sauer
  • 23,698
  • 16
  • 85
  • 87
Goran
  • 6,328
  • 6
  • 41
  • 86
  • Possible duplicate of [Why does WPF Style to show validation errors in ToolTip work for a TextBox but fails for a ComboBox?](http://stackoverflow.com/questions/2260616/why-does-wpf-style-to-show-validation-errors-in-tooltip-work-for-a-textbox-but-f) – Peter Duniho Jun 09 '16 at 08:00

1 Answers1

30

When there are no validation errors, the binding is still trying to access the first element in the ReadOnlyObservableCollection returned by Validation.Errors, but because it is empty, an exception is thrown.

The binding system just swallows the exception, but its still annoying and unnecessary.

Instead of binding like this:

Path=AdornedElement.(Validation.Errors)[0].ErrorContent

..you can do it like this, to avoid the exception:

Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent
Peter Hansen
  • 8,807
  • 1
  • 36
  • 44
  • Thanks, didn't know about CurrentItem, my mistake for not checking. – Goran Sep 21 '12 at 17:44
  • 1
    Thanks for your solution. Sadly, almost all tutorials use `Path=AdornedElement.(Validation.Errors)[0].ErrorContent`. But with `CurrentItem` a new issue arises: ReSharper cannot resolve 'CurrentItem'. Do you have some hints for that, too? – Bernhard Hiller Feb 15 '17 at 10:48
  • 1
    @BernhardHiller you can prefix it like this: `Path=AdornedElement.(Validation.Errors).(componentModel:ICollectionView.CurrentItem).(ValidationError.ErrorContent).(validation:CustomErrorType.Message)` Note the last part 'CustomErrorType' is my custom class - yours will be different. – Jon Barker Apr 28 '17 at 18:51
  • @JonBarker This does not work (for me). I get `Cannot get 'CurrentItem' value (type 'Object') from '(Validation.Errors)' (type 'ReadOnlyObservableCollection`1').` Although doing `.CurrentItem` does work. I'm not sure what is happening in the background when the casting is not done. – RedX Aug 04 '17 at 09:31
  • 3
    In case you have an error reported, see https://stackoverflow.com/a/47556421/73749 – gbianchi Nov 29 '17 at 16:11