Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

背景

  • 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を取ればいいんですが、リアルタイムに更新されなくなっちゃいますからねぇ。リアルタイムに更新し、かつ、末尾に小数点を入力したいんですけど…。

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

h084
C#やWPF周辺について書いていこうと考えています!
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした