bzmind
bzmind

Reputation: 438

How to make custom template for validation rule's default tooltip?

How can I make a custom template for the default tooltip which applies automatically to the control, when using the validation rule? and also is there a way to change the duration of this tooltip?

I mean this tooltip:

TextBox in error state with red border and default error tooltip

XAML:

<Window.Resources>
   <!--Validation Template-->
   <ControlTemplate x:Key="MyErrorTemplate">
      <Border BorderBrush="#e92539" BorderThickness="2" CornerRadius="10">
         <Grid>
            <AdornedElementPlaceholder/>
         </Grid>
      </Border>
   </ControlTemplate>
</Window.Resources>
<TextBox FontSize="13" Validation.ErrorTemplate="{StaticResource MyErrorTemplate}"
         AcceptsReturn="False" Panel.ZIndex="3" x:Name="txtName"
         Style="{StaticResource MyTextBox}" Grid.Row="2">
   <TextBox.Text>
      <Binding Path="txtName" Mode="TwoWay"
               UpdateSourceTrigger="PropertyChanged"
               ValidatesOnDataErrors="True">
         <Binding.ValidationRules>
            <local:ValidateTextBox/>
         </Binding.ValidationRules>
      </Binding>
   </TextBox.Text>
</TextBox>

C#:

class ValidateTextBox : ValidationRule
{
    Regex regex = new Regex(@"[\\/:*?""<>|]");

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        string txtNameText = value as string;
        if (regex.IsMatch(txtNameText))
        {
            return new ValidationResult(false, "A file name can't contain any of the following characters:\n \\ / : * ? \" < > |");
        }
        else
        {
            return new ValidationResult(true, null);
        }
    }
}

Upvotes: 0

Views: 235

Answers (1)

thatguy
thatguy

Reputation: 22079

You have to adapt your TextBox style or create a new one that it sets the ToolTip to the current error.

  • The first setter sets your custom ToolTip template.
  • The second setter uses the ToolTipService to set the attached property ShowDuration, which determines how long the tool tip should be shown. There are other useful properties to explore.
  • The Trigger using the attached property Validation.HasError applies the tooltip only if there is an error. This allows you to specify a default tooltip in a different setter.
  • Since a ToolTip is not part of the same visual tree as its associated control, you have to use a binding to its PlacementTarget (the TextBox) where the validation errors are attached.
<Style x:Key="MyTextBox" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
   <Setter Property="Validation.ErrorTemplate" Value="{StaticResource MyErrorTemplate}"/>
   <Setter Property="ToolTipService.ShowDuration" Value="5000"/>
   <Style.Triggers>
      <Trigger Property="Validation.HasError" Value="True">
         <Setter Property="ToolTip">
            <Setter.Value>
               <ToolTip Template="{StaticResource ToolTipTemplate}"
                        Content="{Binding PlacementTarget.(Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource Self}}"/>
            </Setter.Value>
         </Setter>
      </Trigger>
   </Style.Triggers>
</Style>

You have to adapt your tooltip control template to bind the Text of the TextBlock to the Content property of the templated parent (the ToolTip). This can be done with a TemplateBinding.

<ControlTemplate x:Key="ToolTipTemplate" TargetType="ToolTip">
   <Grid MaxWidth="400">
      <Border Margin="0,0,35,35"
              Background="#212529"
              BorderBrush="#6C757D"
              BorderThickness="1.7"
              CornerRadius="5">
         <Border.Effect>
            <DropShadowEffect Color="Black"
                              Direction="310"
                              ShadowDepth="14"
                              BlurRadius="34"
                              Opacity="0.3"/>
         </Border.Effect>
         <TextBlock Margin="7"
                    Text="{TemplateBinding Content}"
                    VerticalAlignment="Top"
                    TextWrapping="Wrap"
                    HorizontalAlignment="Left"
                    Foreground="#ADB5BD">
         </TextBlock>
      </Border>
   </Grid>
</ControlTemplate>

Remove the Validation.ErrorTemplate from your TextBox, as it is already contained in the style.

Upvotes: 1

Related Questions