背景(前回のあらすじ)
doubleとバインドしているTextBoxに小数点が入力できない!
- C# + XAML
-
TextBox
が数値型のプロパティとバインドしている - リアルタイムに入力値でバインドしているプロパティを更新する
<TextBox Text="{Binding Path=Number,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
このように記述した場合、バインドしているNumber
がint
型だと問題ありません。しかし、double
型だった場合、数字列の末尾に小数点が入力できないんです。
解決方法わかりません!どなたか、ご教授を!というところで終わっていました。
コメントをいただきました!
さっそく、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
を付けています。
<TextBox Text="{Binding Path=Number,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
StringFormat='#,0.#####',
Converter={StaticResource converter}}" />
整数部に3桁ごとのカンマを入れて表示したいんです!
コンバーターが文字列を戻しますので、StringFormat
に指定した数値用の書式指定が使われず、したがってカンマが表示されません!
コンバーター改造!
コンバーターをちょっと改造し、下記のようにしてみました。
- 値が変わらなかったときは、入力文字列(
string
型)を戻す - 値が変わったときは、
StringFormat
を使うように値(double
型)を戻す
//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;
}
}
}
完全に解決したわけではない…
結果は、まぁまぁいいかなって感じですね。末尾の小数点やゼロが入力できるようになりましたが、まだおかしな動作が残っています。
- 整数部の3桁ごとではないところへカンマが入力できてしまう
- 「123.4」となっていた場合に4を削除すると、「123」になる(「123.」になって欲しい)
- 「123.004」となっていた場合に4を削除すると、「123」になる(「123.00」になって欲しい)
1は、改造前のコンバーターでも起きます。コンバーターを付ける前には起きませんでした。2と3は、改造前のコンバーターなら起きません。
というわけで、スッキリ解決!にはなっていません。引き続き、解決法のご教授をお待ちしております!
完結編‼へつづく。