WPF文本框为Double或Float



在我的应用程序中,我有两个文本框,用于设置儿童和成人条目的价格。每当文本框被改变时,事件"textbox_ValueChanged"触发执行"priceChanged()"并将文本框的内容保存到MySQL数据库中。保存价格的列类型为double。在"adultpricetextbox"中输入整数可以很好地工作。(例如),但是当尝试在文本框中写入双精度或浮点数时,有以下几种情况:

1。→用户类型&;5&;然后","然后"5">

在这种情况下,程序在第二个"5"是输入。崩溃的行是cmd.ExecuteNonQuery();,它将值保存到数据库(查看下面的代码)。错误信息看起来像这样

第1行'adults'列的数据被截断">

2。→用户类型&;5&;然后"!"然后"5">

在这种情况下没有崩溃,但是保存到数据库的值不包含点。所以"5.5";会变成"55"

这是将值保存到数据库的代码。它位于一个名为"DatabaseInterface":

的类中。
public static void updatePrice(double _adults, double _children)
{
MySqlConnection cnn = OpenCnn();
MySqlCommand cmd = new MySqlCommand("UPDATE price SET adults = '" + _adults + "', children = '" + _children + "';", cnn);
cmd.ExecuteNonQuery();
}

这是执行"UpdatePrice":

的代码
private void priceChanged()
{
double adultPrice;
double childPrice;
try
{
adultPrice = Convert.ToDouble(adultPriceTextbox.Text);
}
catch
{
adultPrice = 0.0;
}
try
{
childPrice = Convert.ToDouble(childPriceTextbox.Text);
}
catch
{
childPrice = 0.0;
}
DatabaseInterface.updatePrice(adultPrice, childPrice);
}

注意,在这个特殊情况下,有两个输入窗口。一个为儿童定价,另一个为成人定价。我所在的地区是德国,那里的小数用","而不是"。实现用户可以输入整数和浮点数/双精度的文本框的最优雅的解决方案是什么?

补充:在上述文本框中阻止任何字母输入的想法也是受欢迎的,只有数字和";/",">

,而不是绑定到一个文本字符串,只要您的绑定对象的一个属性(MVVM模式)的预期类型的小数,各自浮动或int类型。然后,当您将文本绑定到公共get/set属性时,它将仅存储符合该数据类型的值,从而不会将该值应用于无法转换的坏值属性。

此外,您可以将绑定更改为仅在焦点更改(例如

)之后提交,而不是在每次击键时发送数据。
<TextBox Text="{Binding YourIntegerField, UpdateSourceTrigger=LostFocus}" 
Width="40" MaxLength="3" />

<TextBox Text="{Binding YourDecimalField, UpdateSourceTrigger=LostFocus}" 
Width="70" MaxLength="6" />

MaxLength是实际允许的字符数。对于一个人的年龄,你可能上限为3,但对于定价,你的电话。

最后,通过使用带引号的值构建字符串,您可以进行SQL注入,并且应该对查询进行参数化。尽早学会这样做,特别是在处理实际的基于文本的内容而不是数字时。

MVVM模式为(M) model, (V) view, (VM)ViewModel。模型是所有数据的来源和数据库的数据。视图是对最终用户的所有表示内容,因此是文本框,以及所有其他输入、按钮等。ViewModel是将各个部分连接在一起的粘合剂。你可以在那里找到很多阅读材料。

现在,视图,你得到了。数据所在的模型也存在。视图模型基本上是允许来回公开的对象。因为你不展示你的实际视图(更多的.xaml .xaml.cs,更难添加更多的细节。但是,假设您的。xaml.cs直接与您的。xaml配对。在构造函数中,如果您将DataContext设置为.xaml.cs(或其他实际对象),那么这就是被"绑定"的内容。出现。所以它可能看起来像

namespace YourApp
{
public partial class YourView
{
public YourView()
{
InitializeComponent();
// HERE, you are basically telling the view that anything with "BINDING"
// you want associated to this object.
DataContext = this;
}
// Now, any publicly prepared properties such as
// int, decimal, date, etc can be exposed as bindable in the view
private int _youngAge = 7;
public int YoungAge
{ get { return _youngAge; }
set { _youngAge = value;
DoSomethingOnceAssigned();
}
}
private int _olderAge = 83;
public int OlderAge 
{ get { return _olderAge; }
set { _olderAge = value;
DoSomethingWithOlderAge();
}
}
// similar with any other properties
}
}

现在,在这个场景中,由于我默认了年轻和年老的年龄,如果您运行视图并绑定到这些公共属性(而不是私有属性),那么表单应该分别显示这些年龄。现在,如果您在运行表单时编辑详细信息,并将焦点更改为下一个字段,例如通过click或tab,它应该会击中相应的设置,您可以在这些设置上断点并使用它们进行调试。

看看这是否对你有所帮助,如果还有什么需要帮助的,请告诉我。

对于这两种情况,在pricechange中忽略任何非数字字符,您可以这样做,或者使用ASCII表代替正则表达式,排除'。'或/and '。从被忽略的字符。根据第一个建议,我认为第一个案例的崩溃不会再发生了。对于第二种情况,您可以像Jaime建议的那样输入文化信息,不要忘记将','更改为'。'或转换前的倒数。

最新更新