TextBox に長さ制限を設ける
WPF の TextBox の MaxLength が TSF 環境下で使い物にならない件ですが、Feedback への Microsoft からの回答によると、次期バージョンで何とかなる、のかな?
とはいえ、今抱えてる案件は .NET Framework 3.5 で対応しなきゃいけないわけで。添付プロパティを使って無理矢理対応してみました。時間があったらまた詳しく書きます。
※ バイト数単位で切ることはできません。文字数単位です。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace MaxLength { public class LengthCheck { /// <summary> /// 指定された System.Windows.Controls.TextBox から LengthCheck.MaxLength 添付プロパティの値を取得します。 /// </summary> /// <param name="textBox">プロパティ値の読み取り元の要素。</param> /// <returns>LengthCheck.MaxLength 添付プロパティの値。</returns> public static int GetMaxLength (TextBox textBox) { return (int) textBox.GetValue (MaxLengthProperty); } /// <summary> /// LengthCheck.MaxLength 添付プロパティの値を、指定された System.Windows.Controls.TextBox に設定します。 /// </summary> /// <param name="textBox">添付プロパティを設定する要素。</param> /// <param name="value">設定するプロパティ値。</param> public static void SetMaxLength (TextBox textBox, int value) { textBox.SetValue (MaxLengthProperty, value); } /// <summary> /// LengthCheck.MaxLength 添付プロパティを識別します。 /// </summary> public static readonly DependencyProperty MaxLengthProperty = DependencyProperty.RegisterAttached ("MaxLength", typeof (int), typeof (LengthCheck), new FrameworkPropertyMetadata (0, new PropertyChangedCallback (MaxLengthProperty_Changed))); /// <summary> /// LengthCheck.MaxLength 添付プロパティの値が変更された際に、コントロール側にイベントハンドラを設定します。 /// </summary> /// <param name="d">添付プロパティが設定された要素。</param> /// <param name="e">イベントの引数。</param> static void MaxLengthProperty_Changed (DependencyObject d, DependencyPropertyChangedEventArgs e) { var textBox = d as TextBox; if (textBox != null) { try { int newValue = (int) e.NewValue; // MaxLength プロパティを設定する。 textBox.MaxLength = newValue; if (newValue == 0) { // イベントハンドラ解除 TextCompositionManager.RemoveTextInputStartHandler (d, new TextCompositionEventHandler (OnTextInputStart)); TextCompositionManager.RemovePreviewTextInputHandler (d, new TextCompositionEventHandler (OnPreviewTextInput)); } else { // イベントハンドラ設定 TextCompositionManager.AddTextInputStartHandler (d, new TextCompositionEventHandler (OnTextInputStart)); TextCompositionManager.AddPreviewTextInputHandler (d, new TextCompositionEventHandler (OnPreviewTextInput)); } } catch {// 無視する } } } /// <summary> /// 新しい TextComposition が開始されると発生します。 /// </summary> /// <param name="sender">イベント ハンドラがアタッチされているオブジェクト。</param> /// <param name="e">イベントのデータ。</param> static void OnTextInputStart (object sender, TextCompositionEventArgs e) { // IME が ON の場合は MaxLength を無効にする。 var ime = InputMethod.Current; var textBox = e.Source as TextBox; if (textBox != null && ime.ImeState == InputMethodState.On) textBox.MaxLength = 0; } /// <summary> /// TextComposition が完了したときに発生します。 /// </summary> /// <param name="sender">イベント ハンドラがアタッチされているオブジェクト。</param> /// <param name="e">イベントのデータ。</param> static void OnPreviewTextInput (object sender, TextCompositionEventArgs e) { // 入力確定時に MaxLength を再設定する。 var ime = InputMethod.Current; var textBox = e.Source as TextBox; if (textBox != null && ime.ImeState == InputMethodState.On) { textBox.MaxLength = GetMaxLength (textBox); textBox.Text = textBox.Text.Substring (0, GetMaxLength (textBox)); } } } }
トラックバック
- このエントリーにトラックバック:
- http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/2397
コメント