2

I have ValidationRule by using System.Windows.Controls and that rule return some custom message. But the font size is too small and how can I change the font size?

Screenshot...Textbox content and error content of validation result

Here is example code of WPF Window App...

public class NotEmptyValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        if(value != null)
            return string.IsNullOrWhiteSpace((value ?? "").ToString())
                ? new ValidationResult(false, "Field is required")
                : ValidationResult.ValidResult;
        return ValidationResult.ValidResult;
    }
}

Here is XAML... (Note: Changing Fontsize at TextBox tag didn't work)

<Page...

<TextBox 
        x:Name="txtName" 
        Grid.Row="1" 
        Grid.Column="1" 
        HorizontalAlignment="Left" 
        VerticalAlignment="Top" 
        Width="210" 
        Margin="5,0,0,0"
        FontSize="14"
        Style="{StaticResource MaterialDesignTextBox}">
    <TextBox.Text>
        <Binding Path="RCName" UpdateSourceTrigger="PropertyChanged">
           <Binding.ValidationRules>
                <local2:NotEmptyValidationRule ValidatesOnTargetUpdated="True"/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

</Page>

2 Answers2

4

I ran into this post, and wanted to let folks know that in the current version of Material Design In XAML, there is now a hint assist for this:

            <TextBox
                x:Name="Foo"
                materialDesign:ValidationAssist.FontSize="12"
                Style="{StaticResource MaterialDesignFloatingHintTextBox}"/>

Or you can set it in a style to work on all elements

<Style
    x:Key="MaterialDesignFloatingHintTextBox"
    BasedOn="{StaticResource MaterialDesignFloatingHintTextBox}"
    TargetType="{x:Type TextBox}">
    <Setter Property="materialDesign:ValidationAssist.FontSize" Value="12" />
</Style>
kirikintha
  • 468
  • 5
  • 11
  • This worked like a charm. How did you find this out so other people can help themselves with similar feature updates? – Goku Mar 25 '20 at 20:29
  • 1
    I'll be honest, I cannot remember - I believe I was looking through their github and found the font size problem logged as an issue. Since SO discourages external links, I gave an example! – kirikintha Mar 26 '20 at 19:01
3

For your requirement, you need to modify the Validation.ErrorTemplate. Since you are using MeterialDesign, you can either write your modified style for TextBox, based on existing style or only write modified ErrorTemplate and apply it directly to TextBox using Validation.ErrorTemplate property.

    <Grid xmlns:controlzEx="clr-namespace:ControlzEx" xmlns:wpf="clr-namespace:MaterialDesignThemes.Wpf">
    <Grid.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
        <!--  New Validation ErrorTemplate  -->
        <ControlTemplate x:Key="ModifiedErrorTemplate">
            <ControlTemplate.Resources>
                <DataTemplate DataType="{x:Type ValidationError}">
                    <TextBlock MaxWidth="{Binding ElementName=Placeholder,
                                                  Path=ActualWidth}"
                               Margin="2"
                               HorizontalAlignment="Left"
                               FontSize="12"
                               Foreground="{DynamicResource ValidationErrorBrush}"
                               Text="{Binding ErrorContent}"
                               TextWrapping="Wrap"
                               UseLayoutRounding="false" />
                </DataTemplate>
            </ControlTemplate.Resources>
            <StackPanel>
                <AdornedElementPlaceholder Name="Placeholder" />
                <Border Name="DefaultErrorViewer"
                        Background="{DynamicResource MaterialDesignPaper}"
                        Visibility="Collapsed">
                    <TextBlock MaxWidth="{Binding ElementName=Placeholder,
                                                  Path=ActualWidth}"
                               Margin="0 2"
                               HorizontalAlignment="Left"
                               FontSize="10"
                               Foreground="{DynamicResource ValidationErrorBrush}"
                               Text="{Binding CurrentItem.ErrorContent}"
                               TextWrapping="Wrap"
                               UseLayoutRounding="false" />
                </Border>
                <controlzEx:PopupEx x:Name="ValidationPopup"
                                    AllowsTransparency="True"
                                    IsOpen="False"
                                    Placement="Bottom"
                                    PlacementTarget="{Binding ElementName=Placeholder,
                                                              Mode=OneWay}">
                    <Border Background="{DynamicResource MaterialDesignPaper}">
                        <TextBlock Margin="0 2"
                                   HorizontalAlignment="Left"
                                   FontSize="10"
                                   Foreground="{DynamicResource ValidationErrorBrush}"
                                   Text="{Binding CurrentItem.ErrorContent}"
                                   TextWrapping="Wrap"
                                   UseLayoutRounding="false" />
                    </Border>
                </controlzEx:PopupEx>
            </StackPanel>
            <ControlTemplate.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding ElementName=Placeholder, Path=AdornedElement.(wpf:ValidationAssist.OnlyShowOnFocus)}" Value="False" />
                        <Condition Binding="{Binding ElementName=Placeholder, Path=AdornedElement.(wpf:ValidationAssist.UsePopup)}" Value="True" />
                        <Condition Binding="{Binding ElementName=Placeholder, Path=AdornedElement.(wpf:ValidationAssist.Suppress)}" Value="False" />
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.Setters>
                        <Setter TargetName="ValidationPopup" Property="IsOpen" Value="True" />
                    </MultiDataTrigger.Setters>
                </MultiDataTrigger>

                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding ElementName=Placeholder, Path=AdornedElement.(wpf:ValidationAssist.OnlyShowOnFocus)}" Value="False" />
                        <Condition Binding="{Binding ElementName=Placeholder, Path=AdornedElement.(wpf:ValidationAssist.UsePopup)}" Value="False" />
                        <Condition Binding="{Binding ElementName=Placeholder, Path=AdornedElement.(wpf:ValidationAssist.Suppress)}" Value="False" />
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.Setters>
                        <Setter TargetName="DefaultErrorViewer" Property="Visibility" Value="Visible" />
                    </MultiDataTrigger.Setters>
                </MultiDataTrigger>

                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding ElementName=Placeholder, Path=AdornedElement.(wpf:ValidationAssist.OnlyShowOnFocus)}" Value="True" />
                        <Condition Binding="{Binding ElementName=Placeholder, Path=AdornedElement.(wpf:ValidationAssist.UsePopup)}" Value="True" />
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.Setters>
                        <Setter TargetName="ValidationPopup" Property="IsOpen" Value="{Binding ElementName=Placeholder, Path=AdornedElement.IsKeyboardFocusWithin, Mode=OneWay}" />
                    </MultiDataTrigger.Setters>
                </MultiDataTrigger>

                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding ElementName=Placeholder, Path=AdornedElement.(wpf:ValidationAssist.OnlyShowOnFocus)}" Value="True" />
                        <Condition Binding="{Binding ElementName=Placeholder, Path=AdornedElement.(wpf:ValidationAssist.UsePopup)}" Value="False" />
                    </MultiDataTrigger.Conditions>
                    <MultiDataTrigger.Setters>
                        <Setter TargetName="DefaultErrorViewer" Property="Visibility" Value="{Binding ElementName=Placeholder, Path=AdornedElement.IsKeyboardFocusWithin, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}" />
                    </MultiDataTrigger.Setters>
                </MultiDataTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
        <!--  Derived TextBox Style  -->
        <Style x:Key="ExtendedMaterialDesignTextBox"
               BasedOn="{StaticResource MaterialDesignTextBox}"
               TargetType="TextBox">
            <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ModifiedErrorTemplate}" />
        </Style>
    </Grid.Resources>
    <TextBox x:Name="txtName"
             Grid.Row="1"
             Grid.Column="1"
             Width="210" Style="{StaticResource ExtendedMaterialDesignTextBox}"
             Margin="5,0,0,0"
             HorizontalAlignment="Left"
             VerticalAlignment="Top"
             FontSize="14">
        <TextBox.Text>
            <Binding NotifyOnValidationError="True"
                     Path="RCName"
                     UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <local:NotEmptyValidationRule ValidatesOnTargetUpdated="True" />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
</Grid>

the style for TextBox ErrorTemplate has been copied from here

WPFUser
  • 1,145
  • 7
  • 24
  • Can you explain a little more how do you bind `ControlTemplate` to textbox? Because I can't see any connection between them, and there is a lot going on. I'd really appreciate it. – FCin Dec 20 '16 at 07:49
  • @FCin please see the ExtendedMaterialDesignTextBox style in posted code. Whee the ControlTemplate(ModifiedErrorTemplate) is applied to TextBox's Validation.ErrorTemplate property. – WPFUser Dec 20 '16 at 08:17
  • 1
    @FCin, @WPFUser I think that it is just unmatched key name for `ControlTemplate`. _MaterialDesignValidationErrorTemplate_ for declaration and _ModifiedErrorTemplate_ for usage. – Htet Myat Aung Dec 20 '16 at 08:27
  • Ok, I see this now. This is what I was looking for yesterday and today I see this post :) Thank you. – FCin Dec 20 '16 at 08:30