バイト長で制限したいときもある(五)

バイト長で制限したいときもある(四)。で実装が終わりだと思ってたんだけど、まだ対応できていないケースを発見してしまった。それは、改行コード
WPFのTextBoxは、AcceptReturnというプロパティをTrueに設定すると、改行コードを入力できるようになる。しかし、この改行コードを入力しても、件のPreviewTextInputイベントは発生しない。貼り付けでもないので、コマンド処理ではどうにもならない。
しかし、改行コードも0バイトではないし、データベースにエントリーするときは、その規定文字数にきっちりとカウントされる。なのでバイト数制限をするなら、改行コードもカウントする必要がある。その改行コード対策として、PreviewKeyDownイベントを利用する事にした。
/// <summary>
/// 初期化処理を行います。
/// </summary>
protected override void OnWorkerSet() {

var textBox = this.AttachedElement as TextBox;
textBox.PreviewKeyDown +=
new KeyEventHandler(TextBox_PreviewKeyDown);

this.pasteCommandBinding_ =
new CommandBinding(ApplicationCommands.Paste,
new ExecutedRoutedEventHandler(OnExecutePasted),
new CanExecuteRoutedEventHandler(OnCanExecutePasted));
textBox.CommandBindings.Add(this.pasteCommandBinding_);
TextCompositionManager.AddPreviewTextInputHandler(textBox,
LengthAsBytePropertyWorker.OnPreviewTextInput);

return;
}
これに対する後始末。
/// <summary>
/// 内部リソースを解放します。
/// </summary>
/// <param name="disposing">false:アンマネージリソースのみ解放します。</param>
protected override void OnDispose(bool disposing) {
if (this.IsDisposed) {
return;
}

if (disposing) {
var textBox = this.AttachedElement as TextBox;

textBox.PreviewKeyDown -=
new KeyEventHandler(TextBox_PreviewKeyDown);


if (this.pasteCommandBinding_ != null) {
textBox.CommandBindings.Remove(this.pasteCommandBinding_);
this.pasteCommandBinding_ = null;
}

TextCompositionManager.RemovePreviewTextInputHandler(textBox,
LengthAsBytePropertyWorker.OnPreviewTextInput);

}

base.OnDispose(disposing);
return;
}

イベント用メソッド
/// <summary>
/// TextBox キーダウンイベント直前用ハンドラ
/// </summary>
/// <param name="sender">イベント発生元</param>
/// <param name="e">イベントデータ</param>
private static void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) {
var textBox = sender as TextBox;

if (!textBox.AcceptsReturn || (e.Key != Key.Enter && e.Key != Key.Return)) {
//改行許可で、Enterキー押下時以外は、OnPreviewTextInputメソッドに任せます。
//OnPreviewTextInputは、Enterキーに反応しない感じ
return;
}

if (!TextBoxBehavior.GetLengthAsByte(textBox) || textBox.MaxLength <= 0) {
//バイト制限無し
return;
}

var maxByteLength = textBox.MaxLength;
var currentByteLength = Utils.GetByteLength(textBox.Text);

if (maxByteLength > 0 &&
(currentByteLength + Environment.NewLine.Length) > maxByteLength) {
//制限バイト数を超えるようなら、以下の処理をキャンセルさせる。
e.Handled = true;
}
return;
}

これでだいたい完成かな。これを応用すれば、数値入力のみ可能なTextBoxも可能かな。まあ、その場合、貼り付け用コマンドを共用する必要があるけど。
スポンサーサイト
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0


この記事へのコメント

コメントの投稿

非公開コメント


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

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

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

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