如何在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;
}
}
}
实现我目标的最佳方式是什么?
如果您真的想重置TextBox中显示的值,您必须在DoubleDisplayValue的setter else中按照以下行执行操作:
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
_doubleDisplayValue = originalValue;
NotifyPropertyChanged("DoubleDisplayValue");
}), DispatcherPriority.ContextIdle, null);
我将使用框架的绑定验证系统(请参阅如何实现绑定验证)。
当用户键入无效内容时,最好将无效输入保留在控件中,这样用户就可以将其编辑为有效内容。这比强迫他们从头开始重新输入数据更方便用户。
例如,如果值为0.0,并且用户键入"4.252w35326",我们是否应该强制用户再次键入"4.25233526",而不是简单地删除"w"?