Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Simple Validation Question - setting custom ErrorContent

Tags:

c#

wpf

If I have the following TextBox:

<TextBox Height="30" Width="300" Margin="10" Text="{Binding IntProperty, 
       NotifyOnValidationError=True}" Validation.Error="ContentPresenter_Error">
</TextBox>

And this in the codebehind:

private void ContentPresenter_Error(object sender, ValidationErrorEventArgs e) {
   MessageBox.Show(e.Error.ErrorContent.ToString());
}

If I enter the letter "x" in the text box, the message that pops up is

value 'x' could not be converted

Is there a way to customize this message?

like image 879
Adam Rackis Avatar asked May 27 '11 14:05

Adam Rackis


2 Answers

I dislike answering my own question, but it appears the only way to do this is to implement a ValidationRule, like what's below (there may be some bugs in it):

public class BasicIntegerValidator : ValidationRule {       

    public string PropertyNameToDisplay { get; set; }
    public bool Nullable { get; set; }
    public bool AllowNegative { get; set; }

    string PropertyNameHelper { get { return PropertyNameToDisplay == null ? string.Empty : " for " + PropertyNameToDisplay; } }

    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) {
        string textEntered = (string)value;
        int intOutput;
        double junkd;

        if (String.IsNullOrEmpty(textEntered))
            return Nullable ? new ValidationResult(true, null) : new ValidationResult(false, getMsgDisplay("Please enter a value"));

        if (!Int32.TryParse(textEntered, out intOutput))
            if (Double.TryParse(textEntered, out junkd))
                return new ValidationResult(false, getMsgDisplay("Please enter a whole number (no decimals)"));
            else
                return new ValidationResult(false, getMsgDisplay("Please enter a whole number"));
        else if (intOutput < 0 && !AllowNegative)
            return new ValidationResult(false, getNegativeNumberError());

        return new ValidationResult(true, null);
    }

    private string getNegativeNumberError() {
        return PropertyNameToDisplay == null ? "This property must be a positive, whole number" : PropertyNameToDisplay + " must be a positive, whole number";
    }

    private string getMsgDisplay(string messageBase) {
        return String.Format("{0}{1}", messageBase, PropertyNameHelper);
    }
}
like image 200
Adam Rackis Avatar answered Nov 15 '22 17:11

Adam Rackis


You can use ValidationRules.

For instance, in my case, when a user enters an invalid value into a decimal datagridtextcolumn, instead of the default message "Value could not be converted" I can override it with:

<DataGridTextColumn x:Name="Column5" Header="{x:Static p:Resources.Waste_perc}" Width="auto">
    <DataGridTextColumn.Binding>
        <Binding Path="Waste" ValidatesOnDataErrors="True" UpdateSourceTrigger="LostFocus">
            <Binding.ValidationRules>
                <myLib:DecimalRule />
            </Binding.ValidationRules>
        </Binding>
    </DataGridTextColumn.Binding>
</DataGridTextColumn>

and here's the code for the DecimalRule:

public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
    decimal convertedDecimal;
    if (!decimal.TryParse((string)value, out convertedDecimal))
    {
        return new ValidationResult(false, "My Custom Message"));
    }
    else
    {
        return new ValidationResult(true, null);
    }
}
like image 28
Eduardo Brites Avatar answered Nov 15 '22 17:11

Eduardo Brites