数値入力オンリーのテキストボックスだって作れるんだぞ。

WPFの強みは、拡張性の高さだと思う。後はパフォーマンスだけだ!と言いたい。
仕事では、大抵必要になる「数値のみ入力できるTextBox」だって、その気になれば作れるのだ。というか、実際に作って仕事で使っていたりする。まあ、作らなくても、Extended WPF ToolkitにあるMaskedTextBoxでも良いんだけどね。まあ、その時のメモって事で。
数値入力コントロールとなるのに必要な要件としては

・文字については、半角数値のみ入力を受け付ける。
・負の値を示す「-」は、必ず先頭に持ってくる。
・小数と整数の区切りとなるピリオド「.」は1つだけ受け付ける。
・←や→、コピーや貼り付け等のコマンドは受け付ける必要がある。
・ただし、貼り付けられた(Ctrl+V)ら、その内容をチェックする必要がある。

かなと。仕事では、TextBoxを継承したクラスではなく、添付プロパティとして実装した。
こうすることで、そのプロパティとDataGridのDataGridTextBoxColumnを拡張して、数値入力用の列クラスを実装できる。
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace TawamureDays.Extensions {

/// <summary>
/// TextBoxコントロール用ビヘイビアクラス
/// </summary>
/// <remarks>
/// TextBoxコントロールに対する添付プロパティ(ビヘイビア)を提供するクラスです。<br/>
/// </remarks>
public static class TextBoxBehavior {

/// <summary>数値のみの入力とするかどうか</summary>
public static readonly DependencyProperty AllowInputOnlyNumericProperty =
DependencyProperty.RegisterAttached("AllowInputOnlyNumeric", typeof(bool),
typeof(TextBoxBehavior),
new UIPropertyMetadata(false,
OnAllowInputOnlyNumericPropertyChanged));

/// <summary>
/// AllowInputOnlyNumericプロパティ値変更イベントハンドラ
/// </summary>
/// <param name="dpObj">イベント発生元</param>
/// <param name="e">イベント引数</param>
private static void OnAllowInputOnlyNumericPropertyChanged(
DependencyObject dpObj, DependencyPropertyChangedEventArgs e) {

var textBox = dpObj as TextBox;

if (textBox == null) {
return;
}

textBox.PreviewKeyDown -= new KeyEventHandler(TextBox_PreviewKeyDown);

if ((bool)e.NewValue) {
textBox.PreviewKeyDown += new KeyEventHandler(TextBox_PreviewKeyDown);
}
}

/// <summary>
/// キーダウン直前イベントハンドラ
/// </summary>
/// <param name="sender">イベント発生元</param>
/// <param name="e">イベント引数</param>
private static void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) {
}
}
}
TextBox_PreviewKeyDownメソッドで、不要な入力をキャンセルする。キャンセルする方法は、e.Cancel=trueとするだけ。
入力されたキーの判定は、e.Keyプロパティで可能となる。テンキーの数値とキーボードの上に横に並ぶキーとは値が違うので要注意である。
後は、貼り付けや切り取り等のコマンドだ。これらは、キー入力の判定ではなく、ビルトインコマンド(ApplicationCommandやEditingCommands)として存在するものなので、それらから、CommandBindingを作成し、TextBoxのCommandBindingsプロパティに登録して、結果となる文字列が数値として適正かどうかを判定する。
これらに登録したCommandBindingは後(画面終了時)に必ず削除する必要がある。前にも書いたんだけど、CommandBindingって、そのインスタンスじゃないと削除できない。なので、削除するときまで確保しておく必要がある(Clearメソッドでも良いんだけどね)。
実際に、入力を数値だけに絞れるようになったら、その次は、入力できる範囲等を決める必要が出た。

整数部は何桁まで入力できるか?
小数部は何桁まで入力できるか?
マイナス値を許容しているか?
最大値は?最小値は?

これらを設定するのも、添付プロパティで可能ではあるけど、たくさんあってややこしい。
こういうときは、Behaviorクラスを使うのもいいかと思う。

(2013/2/20追記)
数値だけのTextBoxだってやれるはずだ(壱)。も、数値入力専用TextBoxの話になっている。
スポンサーサイト
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0


この記事へのコメント

コメントの投稿

非公開コメント


サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m