doubleとバインドしているTextBoxに小数点が入力できない！【解決編⁉】

## 背景（前回のあらすじ）
[doubleとバインドしているTextBoxに小数点が入力できない！](https://qiita.com/h084/items/b562526c3dceb693bd64 "前回")

- C# + XAML
- `TextBox`が数値型のプロパティとバインドしている
- リアルタイムに入力値でバインドしているプロパティを更新する

```xml:XAML
<TextBox Text="{Binding Path=Number,
                        Mode=TwoWay,
                        UpdateSourceTrigger=PropertyChanged}" />
```

このように記述した場合、バインドしている`Number`が`int`型だと問題ありません。しかし、`double`型だった場合、**数字列の末尾に小数点が入力できない**んです。

解決方法わかりません！どなたか、ご教授を！というところで終わっていました。

## コメントをいただきました！
さっそく、[albireoさん](https://qiita.com/albireo)にコメントでご教授いただきました！ありがとうございます！

> StackOverflowに「書き戻すときに元の文字列を返すようなコンバータを実装すればいい」ってのがありました。

と紹介していただいたのが、「[Binding to double field with validation][stackoverflow]」です。
[stackoverflow]:https://stackoverflow.com/questions/11223236/binding-to-double-field-with-validation "stackoverflow"

デフォルトの動作で満足できないなら、自分で処理を書きなさい、ってことですね。（そりゃそうだ）

## …おしい！
[リンク先][stackoverflow]に書いてある通りのクラスを作り、コンバーターを付けてみました。

**末尾の小数点が入力できます！**
前回は書いていませんでしたが、できなかった**小数点以下の末尾のゼロの入力もできます！**

おお！素晴らしい！

…**ん？カンマはいずこへ？**

## StringFormatが効いていない！

前回は本題と関係ないと思っていましたので、紹介しているコードに書かなかったのですが、`Binding`マークアップ拡張に`StringFormat`を付けています。

```xml:XAML
<TextBox Text="{Binding Path=Number,
                        Mode=TwoWay,
                        UpdateSourceTrigger=PropertyChanged,
                        StringFormat='#,0.#####',
                        Converter={StaticResource converter}}" />
```

**整数部に3桁ごとのカンマを入れて表示したいんです！**

コンバーターが文字列を戻しますので、`StringFormat`に指定した数値用の書式指定が使われず、したがってカンマが表示されません！

## コンバーター改造！

コンバーターをちょっと改造し、下記のようにしてみました。

- 値が変わらなかったときは、入力文字列（`string`型）を戻す
- 値が変わったときは、`StringFormat`を使うように値（`double`型）を戻す

```c#:コンバーター・クラス
//doubleと文字列のコンバーター
public class DoubleToStringConverter : System.Windows.Data.IValueConverter
{
  private string convertBackString; //入力文字列
  private double? prevValue; //前回表示した値

  //doubleから文字列への変換（表示時に使われる）
  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    try
    {
      if (!(value is double)) return null;

      double newValue = (double)value;
      try
      {
        if (!string.IsNullOrEmpty(convertBackString)
          && prevValue.HasValue && (prevValue == newValue))
        {
          //入力文字列があり、前回表示した値と同じ値を表示するなら、入力文字列をそのまま戻す
          return convertBackString;
        }
        else
        {
          //そうでなければ、値をdouble型で戻す
          //→StringFormatを使ってフォーマットされる
          return newValue;
        }
      }
      finally
      {
        prevValue = newValue;
      }
    }
    finally
    {
      convertBackString = null;
    }
  }

  //文字列からdoubleへの変換（入力時に使われる）
  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    //入力文字列を保存する
    convertBackString = value as string;

    if (!string.IsNullOrEmpty(convertBackString)
      && double.TryParse(convertBackString, out double newValue))
    {
      //入力文字列をパーズして戻す
      return newValue;
    }
    else
    {
      return null;
    }
  }
}
```

## 完全に解決したわけではない…

結果は、まぁまぁいいかなって感じですね。末尾の小数点やゼロが入力できるようになりましたが、まだおかしな動作が残っています。

1. 整数部の3桁ごとではないところへカンマが入力できてしまう
1. 「123.4」となっていた場合に4を削除すると、「123」になる（「123.」になって欲しい）
1. 「123.004」となっていた場合に4を削除すると、「123」になる（「123.00」になって欲しい）

1は、改造前のコンバーターでも起きます。コンバーターを付ける前には起きませんでした。2と3は、改造前のコンバーターなら起きません。

というわけで、スッキリ解決！にはなっていません。引き続き、**解決法のご教授をお待ちしております！**

[完結編‼](https://qiita.com/h084/items/1c266839bad95f6f90fe)へつづく。