Это интересный вопрос. Я не уверен, что у меня есть полное решение, но я хотел бы выбросить пару идей.
Что вы думаете о создании нового класса, производного от 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 для поддержки вашего правила проверки.
Мое предложение по общему признанию имеет свои недостатки.
- Этот подход потребовал бы, чтобы у вас был код, связанный с проверкой, в двух местах, и они должны были бы соответствовать. (Возможно, вы также можете переопределить OnTextChanged и установить вместо этого красную рамку.)
- Этот подход требует, чтобы вы помещали правила в слой представления, а не в бизнес-объекты, которые вы можете или не можете найти приемлемыми.