それは興味深い質問です。完全な解決策があるかどうかはわかりませんが、いくつかのアイデアを捨てたいと思います。
TextBox から派生した新しいクラスを作成することについてどう思いますか? MinValue と MaxValue の 2 つの依存関係プロパティを持つことができます。次に、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 を使用して検証規則をサポートできます。
私の提案には確かに欠点があります。
- このアプローチでは、検証関連のコードを 2 つの場所に配置する必要があり、それらが一致する必要があります。(おそらく、OnTextChanged もオーバーライドして、代わりに赤い境界線を設定することができます。)
- このアプローチでは、ルールをビジネス オブジェクトではなくビュー レイヤーに配置する必要がありますが、これが受け入れられる場合とそうでない場合があります。