- PR -

ComboBoxのKeyPressイベントのキャンセル

1
投稿者投稿内容
junya_s0
常連さん
会議室デビュー日: 2002/12/23
投稿数: 26
投稿日時: 2002-12-24 16:53
こんにちは。
VB.NETでWindowsアプリケーションの開発を行っています。
ComboBoxのKeyPressイベントについて質問があります。

ComboBoxの直接入力を数値のみにしたいのですが、
数値以外の場合にComboBoxのKeyPressイベント内で
e.handled=True(eはSystem.Windows.Forms.KeyPressEventArgs)
を設定しても入力がキャンセルされません。

ComboBoxの直接入力をキャンセルさせることは
できるのでしょうか?
ちなみに、ComboBoxはDropDownStyle=DropDownに設定されています。

それでは、よろしくお願いします。
のり
会議室デビュー日: 2002/06/04
投稿数: 12
投稿日時: 2002-12-24 17:17
こんにちは。
私も同様の問題にぶつかったことがあります。


どうもComboBoxという部品は、DropDown属性のときは内部的にTextBoxも持つような構成になっているのではないかと推測しています。(これはあくまでもイメージですが)
そのため、テキスト入力のイベント処理がTextBoxで行うようにはいかないということです。
WndProcをOverrideして調べてみるとわかりますが、DropDown属性ではテキスト入力時にWM_CHARを取得していません。

前置きが長くなりましたが、私は以下のように対処しました。
※ComboBoxの派生クラスを作成しています。
派生クラスを作成しなくても同様のことは行えると思います。

Protected Overrides Sub OnKeyPress(ByVal e As
System.Windows.Forms.KeyPressEventArgs)

'入力文字制御
If IsInvalidInput(e.KeyChar) = True Then
'入力不可の場合
Beep()
Me.Text = Me.Text.Replace(e.KeyChar, "")
End If


TextBoxとは異なり、Textが変更されてからKeyPressが発生するようです。
(だから、e.Handledを制御してもうまくいかないとも言えますね)
そのことを利用して、不正な入力(junya_s0の場合は数字以外ですね)を検知したとき、その文字をTextから消してしまうというやり方です。


但し、この方法では一瞬入力した文字が表示されてから、その文字が消えるというのが見えてしまうという問題があります。


また、試してはいないのですが、後になって知った情報があります。
ComboBoxのプロテクトメソッドにProcessCmdKeyというのがあります。
これはキーボート入力を仮想キーコードで受け取るメソッドなのですが、このメソッドが呼ばれるタイミングがキーボート処理の最初のほうだということがわかっています。
よって、以降の処理をカスタマイズできる可能性があるわけです。
あまり、今回の件を解決するのに都合の良いメソッドではないと思いますが・・・
また、このメソッドを活用するには派生クラスを作成しなければなりません。

ちなみに私はTabキーとEnterキーの制御をするためにこのメソッドを利用してます。




junya_s0
常連さん
会議室デビュー日: 2002/12/23
投稿数: 26
投稿日時: 2002-12-24 18:38
派生クラスを作り、ProcessCmdKeyのほうでやってみました。

うまくいったのですが、アルファベット等のNG文字をselect caseのcase elseに
指定したため、NGではない文字はすべて戻り値としてFalseを返さなければならず、
BackSpace、Delete、Tab、Shift+Tab、カーソルキー、マウスボタン等々
個々に指定する必要があるのでかなりしんどいですね。

'もしかしたらNG文字を指定したほうが早いかもしれない・・・

以上、報告です。ありがとうございました。
のり
会議室デビュー日: 2002/06/04
投稿数: 12
投稿日時: 2002-12-25 12:40
junya_s0さん、こんにちは。


ProcessCmdKeyを利用する方法を試されているのですね。
junya_s0さんのおっしゃっているようにこのメソッドで入力制限をするのはいろいろと不都合があって大変だと思います。
特に問題だと思うのが、IME文字です。
つまり、漢字とかひらがななどをどうやって入力制限するのかということです。
そのことを考慮しなくても良いのであればいいんですが。


最初に示したTextプロパティをOnKeyPressで強制的に編集するという方法であれば、IME文字の入力制限も実現できます。


キーボード系のProcess〜という名前のメソッドは他にもあります。
ProcessKeyEventArgs()やProcessKeyMessage()というメソッドです。
もしかするとこちらのメソッドの方が入力制限をするのに使えるかもしれません。
(ただ未調査です。ごめんなさい。)


すいません、最初にお知らせした情報が中途半端でした。


念のため補足しました。

1

スキルアップ/キャリアアップ(JOB@IT)