Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constraint length of Text in TextBox by its encoded representation

I have a TextBox in WPF. I want to restrict the length of the text in the TextBox. There is an easy way to restrict the number of characters by the property MaxLength.

In my use case I need to restrict the text not by the number of characters but by length of the binary representation of the text in a given encoding. As the program is used by germans there are some umlaut, that consume two byte.

I already have a method, that checks, if a given string fits into the given length:

public bool IsInLength(string text, int maxLength, Encoding encoding)
{
    return encoding.GetByteCount(text) < maxLength;
}

Does anybody has an idea how to tie this function to the textbox in a way, that the user has no possibility to enter too much characters to exceed the maximum byte length.

Solutions without EventHandler are prefered as the TextBox is inside a DataTemplate.

like image 614
scher Avatar asked Aug 01 '17 09:08

scher


1 Answers

A ValidationRule may be what fits the bill here. Here's an example implementation:

public sealed class ByteCountValidationRule : ValidationRule
{
    // For this example I test using an emoji (😄) which will take 2 bytes and fail this rule.
    static readonly int MaxByteCount = 1;

    static readonly ValidationResult ByteCountExceededResult = new ValidationResult(false, $"Byte count exceeds the maximum allowed limit of {MaxByteCount}");

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        var val = value as string;

        return val != null && Encoding.UTF8.GetByteCount(val) > MaxByteCount
            ? ByteCountExceededResult
            : ValidationResult.ValidResult;
    }
}

And the XAML use:

    <TextBox.Text>
        <Binding Path="Text" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:ByteCountValidationRule />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>

Now you can either put 1 emoji or 2 ascii characters to trigger failure (since either will exceed 1 byte limit).

like image 107
Maverik Avatar answered Sep 29 '22 09:09

Maverik