如何在WPF中创建一个带绑定的验证TextBox,在无效条目后切换回最后一个有效值

本文关键字:无效 TextBox 有效值 最后一个 验证 绑定 创建 WPF 一个 | 更新日期: 2023-09-27 18:30:04

WPF中,我想制作一个TextBox,它验证用户输入,只允许解析为双精度的输入。当框失去焦点(Binding更新)时,如果用户输入了无效输入,我希望框切换回以前的状态。

这看起来应该很简单,但我无法让它发挥作用。无论我尝试了什么,TextBox都会继续显示用户输入的无效字符串,即使该属性正在正确验证输入,并且除非有效,否则不会保存。我觉得在解析失败时通知属性更改应该会导致TextBox重置为旧值,但事实并非如此。

我的视图模型有一个属性:

private double _doubleDisplayValue;
public string DoubleDisplayValue
{
    get { return _doubleDisplayValue.ToString(); }
    set
    {
        double result;
        bool success = double.TryParse(value, out result);
        if(success)
        {
            if(_doubleDisplayValue != result)
            {
                _doubleDisplayValue = result;
                NotifyPropertyChanged("DoubleDisplayValue");
            }
        }
        else
        {
            // I feel like notifying property changed here should make the TextBox
            // update back to the old value (still in the backing variable), but
            // it just keeps whatever invalid string the user entered.
            NotifyPropertyChanged("DoubleDisplayValue");
        }
    }   
}

我设置了我的TextBox(我在代码背后工作):

// . . .
TextBox textBox = new TextBox();
Binding b = new Binding("DoubleDisplayValue");
b.Mode = BindingMode.TwoWay;
// assume the DataContext is properly set so the Binding has the right source
textBox.SetBinding(TextBox.TextProperty, b);
// . . .

我也尝试过将属性修改为这个,但仍然不起作用:

private double _doubleDisplayValue;
public string DoubleDisplayValue
{
    get { return _doubleDisplayValue.ToString(); }
    set
    {
        double result;
        bool success = double.TryParse(value, out result);
        if(success)
        {
            // got rid of the if
            _doubleDisplayValue = result;
            NotifyPropertyChanged("DoubleDisplayValue");                
        }
        else
        {
            // Figured maybe I need to retrigger the setter
            DoubleDisplayValue = _doubleDisplayValue;
        }
    }   
}

实现我目标的最佳方式是什么?

如何在WPF中创建一个带绑定的验证TextBox,在无效条目后切换回最后一个有效值

如果您真的想重置TextBox中显示的值,您必须在DoubleDisplayValue的setter else中按照以下行执行操作:

Application.Current.Dispatcher.BeginInvoke(new Action(() =>
    {
        _doubleDisplayValue = originalValue;
        NotifyPropertyChanged("DoubleDisplayValue");
    }), DispatcherPriority.ContextIdle, null);

我将使用框架的绑定验证系统(请参阅如何实现绑定验证)。

当用户键入无效内容时,最好将无效输入保留在控件中,这样用户就可以将其编辑为有效内容。这比强迫他们从头开始重新输入数据更方便用户。

例如,如果值为0.0,并且用户键入"4.252w35326",我们是否应该强制用户再次键入"4.25233526",而不是简单地删除"w"?