Jviaches
Jviaches

Reputation: 843

EmptyTextValidationRule not behave as requested

Requirements: We have TextBox and when it is empty and loses focus, textbox will mark itself as "need to be filled" and raise popup.

Implementation: So far i became with following solution:

Important NOTE: i cannot afford usage of code behind since this should be generic for ant textbox.

The problem is that my code is not working when textbox is empty and looses its focus.

<Window.Resources>
    <Style TargetType="{x:Type TextBox}">
        <Setter Property="Validation.ErrorTemplate">
            <Setter.Value>
                <ControlTemplate>
                    <DockPanel>
                        <Grid DockPanel.Dock="Right" Width="16" Height="16" VerticalAlignment="Center" Margin="3 0 0 0">
                            <Ellipse Width="16" Height="16" Fill="Red" />
                            <Ellipse Width="3" Height="8" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0 2 0 0" Fill="White" />
                            <Ellipse Width="2" Height="2" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0 0 0 2" Fill="White" />
                        </Grid>
                        <Border BorderBrush="Red" BorderThickness="2" CornerRadius="2">
                            <AdornedElementPlaceholder />
                        </Border>
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>                
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<Grid>
    <TextBox Height="20" Width="100" />
    <TextBox Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" MinWidth="150" MaxWidth="180" Margin="5,0">
        <TextBox.Text>
            <Binding Path="IncidentName" Mode="TwoWay" NotifyOnSourceUpdated="True" UpdateSourceTrigger="LostFocus">
                <Binding.ValidationRules>
                    <validators:EmptyTextValidationRule />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
</Grid>

EmptyTextValidationRule:

    public class EmptyTextValidationRule : ValidationRule
{
    private string m_errorText;
    private const string TEXT_REQUERIED = "Text filed should not be empty";

    public EmptyTextValidationRule()
    {
    }

    public string ErrorText
    {
        get { return m_errorText; }
        set
        {
            m_errorText = value;
        }
    }

    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        string enterendText = value.ToString();
        if (string.IsNullOrEmpty(enterendText))
        {
            if (string.IsNullOrEmpty(ErrorText))
                return new ValidationResult(false, TEXT_REQUERIED);
            else
                return new ValidationResult(false, ErrorText);
        }

        return new ValidationResult(true, null);
    }
}

Upvotes: 1

Views: 63

Answers (1)

Sheridan
Sheridan

Reputation: 69959

This is not an attempt to answer your question, instead just pointing out a mistake in your code:

public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
    string enterendText = value.ToString(); //<< You'll get error here if value is null
    if (string.IsNullOrEmpty(enterendText)) //<< No point checking here... too late!
    {
        if (string.IsNullOrEmpty(ErrorText))
            return new ValidationResult(false, TEXT_REQUERIED);
        else
            return new ValidationResult(false, ErrorText);
    }

    return new ValidationResult(true, null);
}

Using this code, if value was ever null, then you'd get an error in the first if statement condition... you should do something like this instead:

string enterendText = string.Empty;
if (value == null || (enterendText = value.ToString()).Trim() == string.Empty)
{
    ...
}

Upvotes: 2

Related Questions