将 ValidationRule 和值转换器组合用于文本框

发布于 2024-10-18 21:33:12 字数 438 浏览 2 评论 0原文

我有一个简单的问题,我只是找不到好的解决方案。 我有一个绑定到双属性值的文本框。用户可以在文本框中输入值,但我只想允许 0 到 100 之间的值。如果在文本框仍具有焦点时输入无效值,我希望在文本框周围显示一个红色框 (UpdateSourceTrigger="PropertyChanged" )。如果用户单击远离文本框的位置,我想使用 UpdateSourceTrigger="LostFocus" 上的值转换器来限制该值。

执行验证规则或转换器都很容易,但我无法将它们组合起来,因为我希望验证在 UpdateSourceTrigger="PropertyChanged" 上触发,而转换器应在 UpdateSourceTrigger="LostFocus" 上触发。不幸的是,在 TextBox.Text 上设置绑定时,我只能选择其中之一。

关于如何实现此功能有什么好的想法吗?

谢谢你

/彼得

I have a simple problem that I just cant find a good solution for.
I have a textbox bound to a double property value. The user can enter values into the textbox, but I only want to allow values between 0 and 100. I would like to show a red box around the textbox if an invalid value is entered while the textbox still has focus (UpdateSourceTrigger="PropertyChanged"). Should the user click away from the textbox, I want to clamp the value using a value converter on UpdateSourceTrigger="LostFocus".

Its easy to do either the validation rule or the converter, but I can not combine them as I want the validation to trigger on UpdateSourceTrigger="PropertyChanged" and the converter should trigger on UpdateSourceTrigger="LostFocus". Unfortunately I can only choose either one or the other when setting up the binding on my TextBox.Text.

Any good ideas about how I could implement this functionality?

Thank you

/Peter

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

骷髅 2024-10-25 21:33:12

这是一个有趣的问题。我不确定我是否有完整的解决方案,但我想提出一些想法。

您认为创建一个派生自 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. 这种方法要求您将规则放在视图层而不是业务对象中,您可能会或可能不认为可以接受。

That's an interesting question. I'm not sure I have a complete solution, but I'd like to throw out a couple ideas.

What do you think of creating a new class that derives from TextBox? It could have two dependency properties, MinValue and MaxValue. Then it could override OnLostFocus. (Disclaimer: I haven't tested the following code.)

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();
    }
}

This would eliminate the need for a converter, and your binding can use UpdateSourceTrigger=PropertyChanged to support your validation rule.

My suggestion admittedly has its drawbacks.

  1. This approach would require you to have validation-related code in two places, and they'd need to match. (Maybe you could override OnTextChanged too, and set the red border there instead.)
  2. This approach requires you to put rules in the view layer rather than in business objects, which you may or may not find acceptable.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文