Объединение ValidationRule и преобразователей значений для текстового поля - PullRequest
3 голосов
/ 21 февраля 2011

У меня есть простая проблема, для которой я просто не могу найти хорошее решение.У меня есть текстовое поле, связанное с двойным значением свойства.Пользователь может вводить значения в текстовое поле, но я хочу разрешить значения от 0 до 100. Я хотел бы показать красное поле вокруг текстового поля, если введено недопустимое значение, когда текстовое поле все еще имеет фокус (UpdateSourceTrigger = "PropertyChanged").Если пользователь щелкнет вдали от текстового поля, я хочу зафиксировать значение с помощью преобразователя значений на UpdateSourceTrigger = "LostFocus".

Легко сделать либо правило проверки, либо преобразователь, но я не могу их объединитьпоскольку я хочу, чтобы проверка запускалась по UpdateSourceTrigger = "PropertyChanged", а конвертер должен запускаться по UpdateSourceTrigger = "LostFocus".К сожалению, я могу выбрать только одно или другое при настройке привязки на моем TextBox.Text.

Есть хорошие идеи о том, как я мог бы реализовать эту функцию?

Спасибо

/ Peter

1 Ответ

0 голосов
/ 04 апреля 2011

Это интересный вопрос. Я не уверен, что у меня есть полное решение, но я хотел бы выбросить пару идей.

Что вы думаете о создании нового класса, производного от TextBox? Он может иметь два свойства зависимости, MinValue и MaxValue. Тогда это могло бы переопределить OnLostFocus. (Отказ от ответственности: я не проверял следующий код.)

public class NumericTextBox : TextBox
{
    public static readonly DependencyProperty MinValueProperty =
        DependencyProperty.Register("MinValue", typeof(double), typeof(NumericTextBox), new UIPropertyMetadata(Double.MinValue));

    public static readonly DependencyProperty MaxValueProperty =
        DependencyProperty.Register("MaxValue", typeof(double), typeof(NumericTextBox), new UIPropertyMetadata(Double.MaxValue));

    public double MinValue
    {
        get { return (double)GetValue(MinValueProperty); }
        set { SetValue(MinValueProperty, value); }
    }

    public double MaxValue
    {
        get { return (double)GetValue(MaxValueProperty); }
        set { SetValue(MaxValueProperty, value); }
    }

    protected override void OnLostFocus(System.Windows.RoutedEventArgs e)
    {
        base.OnLostFocus(e);

        double value = 0;

        // Parse text.
        if (Double.TryParse(this.Text, out value))
        {
            // Make sure the value is within the acceptable range.
            value = Math.Max(value, this.MinValue);
            value = Math.Min(value, this.MaxValue);
        }

        // Set the text.
        this.Text = value.ToString();
    }
}

Это устранит необходимость в преобразователе, и ваша привязка может использовать UpdateSourceTrigger = PropertyChanged для поддержки вашего правила проверки.

Мое предложение по общему признанию имеет свои недостатки.

  1. Этот подход потребовал бы, чтобы у вас был код, связанный с проверкой, в двух местах, и они должны были бы соответствовать. (Возможно, вы также можете переопределить OnTextChanged и установить вместо этого красную рамку.)
  2. Этот подход требует, чтобы вы помещали правила в слой представления, а не в бизнес-объекты, которые вы можете или не можете найти приемлемыми.
...