8

Branching off of this question -

When attaching a validation error template to my custom textbox like this -

<local:CustomTextBox CustomText="{Binding ViewModelProperty}" Validation.ErrorTemplate="{StaticResource errorTemplate}"/>

<ControlTemplate x:Key="errorTemplate">
    <DockPanel>
        <Border BorderBrush="Red" BorderThickness="1">
            <AdornedElementPlaceholder x:Name="controlWithError"/>
        </Border>
        <TextBlock Foreground="Red" FontSize="20" FontFamily="Segoe UI" Margin="3,0,0,0"  MouseDown="Exclamation_MouseDown"  Tag="{Binding AdornedElement.(Validation.Errors)[0].ErrorContent, ElementName=controlWithError}">!</TextBlock>
    </DockPanel>
</ControlTemplate>

If there was a validation error in the ViewModelProperty, my application was throwing an exception -

Key cannot be null.
Parameter name: key

I'm not sure why this is happening. Is there something that needs to be done in order to assign a new error template to a custom control?

UPDATE:

I've figured out that the issue is with the Tag property in the error template. If I remove the Tag, it works just fine.

Thanks

Community
  • 1
  • 1
Duke Cyrillus
  • 1,217
  • 2
  • 14
  • 29

1 Answers1

11

Alright so the way I managed to fix the issue was by removing the AdornedElement keyword and changing the error template as follows:

<local:CustomTextBox CustomText="{Binding ViewModelProperty}">
    <Validation.ErrorTemplate>
        <ControlTemplate>
            <DockPanel>
                <Border BorderBrush="Red" BorderThickness="1">
                    <AdornedElementPlaceholder x:Name="controlWithError"/>
                </Border>
                <TextBlock Foreground="Red" FontSize="20" FontFamily="Segoe UI" Margin="3,0,0,0"  MouseDown="Exclamation_MouseDown">!</TextBlock>
            </DockPanel>
        </ControlTemplate>
    </Validation.ErrorTemplate>
    <local:CustomTextBox.Style>
        <Style TargetType="{x:Type local:CustomTextBox}">
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="true">
                    <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
                    <Setter Property="Tag" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </local:CustomTextBox.Style>
</local:CustomTextBox>

What I don't understand is why it behaves differently when using the AdornedElement keyword but works fine when binding the Tag/Tooltip using the RelativeSource. While the problem is solved, I would welcome any ideas as to why this happened.

Thanks

Duke Cyrillus
  • 1,217
  • 2
  • 14
  • 29
  • 6
    I realise that this is an old question, but I'm guessing that your first example threw an Exception because there were NO errors in the `Validation.Errors` collection, but you were trying to bind to the `ErrorContent` property of the first (non-existent) error. In your solution, you only opt to bind to the error message when the `HasError` property was true and therefore, when there was one or more errors in the collection. Even in this second example, you should still see the Exception displayed in the Output window of Visual Studio. – Sheridan Jul 21 '16 at 13:12