Как обрабатывать проверку в пользовательском текстовом поле

#wpf #wpf-controls

#wpf #wpf-элементы управления

Вопрос:

У меня есть пользовательское текстовое поле для обработки измерений (футы, дюймы, мм), которое имеет пару свойств зависимостей, которые определяют, каким должно быть форматирование поля, когда поле теряет фокус. Я получил все преобразования, происходящие в OnLostFocus функции, потому что преобразования в середине ввода не будут работать. В OnLostFocus я преобразую значение в число в зависимости от некоторых других свойств DP и устанавливаю свойство измерения. Все это отлично работает.

Мой вопрос в том, как мне обрабатывать проверку? Когда кто-то вводит недопустимое значение, я хочу, чтобы текстовое поле стало красным, так же, как вы могли бы сделать с привязкой, которая имеет ValidatesOnExceptions=true . Я попробовал что-то вроде приведенного ниже в блоке catch OnLostfocus

     protected override void OnLostFocus(RoutedEventArgs e)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(Text))
            {
                Text = "0";
            }
            if (IsMetric)
            {
                var measurement = convertStuffHere();
                Text = measurement.Text;
                Measurement = measurement.Value;
            }
            else
            {
                var measurement = convertOtherStuffHere();
                // convert and formatting stuff here...

                Text = measurement.Text;
                Measurement = measurement.Value;
            }

            var binding = this.GetBindingExpression(TextBox.TextProperty);
            if (binding != null)
                Validation.ClearInvalid(this.GetBindingExpression(TextBox.TextProperty));

        }
        catch (Exception)
        {
            var rule = new DataErrorValidationRule();
            var binding = this.GetBindingExpression(TextBox.TextProperty);
            if (binding != null)
            {

                ValidationError validationError = new ValidationError(rule, this.GetBindingExpression(TextBox.TextProperty));

                validationError.ErrorContent = "This is not a valid input";

                Validation.MarkInvalid(this.GetBindingExpression(TextBox.TextProperty), validationError);
            }


        }
        finally
        {
            base.OnLostFocus(e);
        }
    }
 

Это почти работает, но ошибка проверки появляется с опозданием. Я должен потерять фокус, получить фокус и снова потерять фокус, прежде чем вокруг текстового поля появится красное поле.

Я использую его как <myns:MeasurementTextBox Text="{Binding MeasurementText1, ValidatesOnExceptions=True}" Margin="10" IsMetric="True"></myns:MeasurementTextBox>

Ответ №1:

Вы можете использовать TextBoxBase.Событие TextChanged вместо UIElement.Потерянный фокус.

Комментарии:

1. Ахах. Это сработало. В итоге я проанализировал значение в TextChanged, а затем форматировал в потерянном фокусе. Я беспокоился, что выполнение этого в TextChanged заставит привязку обновляться каждый раз при вводе ввода (я хотел, чтобы это было в LostFocus), но я предполагаю, что UpdateSourceTrigger предназначен для управления этим. Спасибо!