LoginSignup
5
5

More than 5 years have passed since last update.

doubleとバインドしているTextBoxに小数点が入力できない!

Last updated at Posted at 2018-09-22

背景

  • C# + XAML
  • TextBoxが数値型(intdouble)とバインドしている
  • リアルタイムに入力値でバインドしているプロパティを更新する
<TextBox Text="{Binding Path=Number, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

TextBox.Textプロパティを、数値型のNumberとバインドしています。

Mode=TwoWayとしていますので、TextBoxに入力するとその値をバインドしているNumberへ書き込みます。(これはTextBoxのデフォルトの動作ですから、記述しなくても構いませんね)

また、UpdateSourceTrigger=PropertyChangedとしていますので、TextBoxのデフォルトの動作であるフォーカスが外れたときではなく、値を入力した瞬間にNumberへ書き込みます。

int(long)だとバッチリ!

バインドしているNumberが、intlongなど整数型だと、何の問題もなく動作します!

ちなみに、数字以外の文字列を入れた場合は、枠が赤くなり、入力に誤りがあることも自動的に表示してくれます!
入力に誤りがあれば、バインドしているNumberも更新されません。

キャプチャ.PNG

なんと便利!

double(float)だと…

ところが、バインドしているNumberが、doublefloatなど小数点以下を含む数値型になると、問題が生じます!

小数点が入力できないんです!

「123.45」と左の1から順に入力していくと、小数点が入力されず「12345」になってしまいます!

小数点が全く入力できないかというと、そうでもなくて、「12345」と入力した後、「3」と「4」の間にカーソルを置き、「.」を入力すると、正しく「123.45」になります。

つまり、数字列の最後(末尾)へ小数点が入力できないんです!

どうなってるの?(推測)

System.Windows.Data Error: 7 : ConvertBack cannot convert value '123a' (type 'String'). BindingExpression:Path=Model.Number1; DataItem='SimpleCalcViewModel' (HashCode=20876819); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String') FormatException:'System.FormatException: 入力文字列の形式が正しくありません。
   場所 System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   場所 System.Number.ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt)
   場所 System.String.System.IConvertible.ToInt64(IFormatProvider provider)
   場所 System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   場所 MS.Internal.Data.SystemConvertConverter.ConvertBack(Object o, Type type, Object parameter, CultureInfo culture)
   場所 System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverter converter, Object value, Type sourceType, Object parameter, CultureInfo culture)'

数値以外を入力したときに、Visual Studioの出力ウィンドウに出る例外のバックトレースから、次のような機序になっているようです。

  1. TextBoxに数字(文字)を入力する
  2. 入力された文字列全体を、Number.ParseInt64メソッドやNumber.ParseDoubleメソッドを使って、数値に変換する
  3. 変換に成功したら、その数値をTextBoxに表示する
  4. バインドしているプロパティに書き込む

ここで問題になるのが、「変換に成功したら、その数値をTextBoxに表示する」ところです。

末尾に小数点を入力すると、たとえば「123.」という文字列になります。
これをNumber.ParseDoubleメソッドが変換すると、123という数値になります。
123という数値は、表示すると「123」になり、小数点はなくなってしまいます!

どうすればいいの?(HELP!)

では、どうすればいいのかですが、すみません!まだ、わかっていません!
どなたか、ご教授いただければ幸いです!

UpdateSourceTrigger=PropertyChangedを取ればいいんですが、リアルタイムに更新されなくなっちゃいますからねぇ。リアルタイムに更新し、かつ、末尾に小数点を入力したいんですけど…。

解決編⁉完結編‼へつづく。

5
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5