カスタムコントロールについて

タグの編集
投稿者   (学生) 投稿日時 2022/5/20 15:55:03
エンターキーを押すと次にコントロールに移動する機能を搭載したカスタムコントロールであるテキストボックスを用いてフォームを作っています。

今までは数字のみに制限したい場合は、カスタムコントロールのクラス内のKeyPressイベントに以下のようなものを記載して全てのテキストボックスを制御しておりました。

 If (e.KeyChar < "0"c OrElse "9"c < ) AndAlso e.KeyChar <> Controls.Back Then

~~~

End If

質問をいたしましては、今回はテキストボックスごとに全角のみや数字のみを制御したいため、Formの中のテキストボックスのKeyPressイベントに上記の分を記載したところ
e.KeyCharの部分が
エラー BC30456 'KeyChar' は 'EventArgs' のメンバーではありません。
と出てしまいます。

    Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress

    End Sub

どこに記載すれば問題は解決するでしょうか?
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2022/5/20 18:10:38
> エンターキーを押すと次にコントロールに移動する機能を搭載したカスタムコントロールであるテキストボックスを用いてフォームを作っています。

KeyPreview プロパティを True にしておけば、TextBox 側で個別実装せずとも、
フォーム側だけで  Enter 移動を実装することができますよ。
https://dobon.net/vb/dotnet/control/enterliketab.html


> Formの中のテキストボックスのKeyPressイベントに上記の分を記載したところ
それはコーディング上のミスという可能性が高いです。

KeyPress に限りませんが、イベントハンドラーを新規作成する際に、どのような手順をとりましたか?
もしも下記の (1) だとしたら、手順が間違っています。

(1) 既存のイベントハンドラー(たとえば TextBox1_TextChanged など)を流用して、
 Handles TextBox1.TextChanged の部分を
 Handles TextBox1.KeyPress に手動で変更した。

(2) デザイン時に、コントロールを選択した状態で、プロパティウィンドウの
 稲妻⚡アイコンを選び、KeyPress イベントの欄をダブルクリックして自動生成させた。

(3) 上記 (2) の⚡で、イベント名をダブルクリックするのではなく、KeyPress イベントの欄に
 イベントハンドラー名を手動で記入し(たとえば TextBox1_KeyPress など)、Enter キーで自動生成。

(4) フォームデザイナーではなく、フォームの コード エディター側で、
 上部の 3 つのドロップダウンリストのうち、中央のボックスから TextBox1 を選択してから、
 右側のボックスで KeyPress を選択し、イベントハンドラーを自動生成。


> e.KeyCharの部分が
> エラー BC30456 'KeyChar' は 'EventArgs' のメンバーではありません。
> と出てしまいます。
> Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
この宣言を見る限り、引数 e の型は EventArgs ではなく KeyPressEventArgs になっています。
そのため、この箇所で e.KeyChar を使うことは問題ありません。

エラーになっているのは、おそらく別の場所のはずです。
エラーメッセージに示されているファイル名と行番号を、再度確認してみてください。
(エラー一覧のメッセージをダブルクリックすると、該当のエラー箇所にジャンプするはず)
投稿者   (学生) 投稿日時 2022/5/24 09:05:03
ご回答ありがとうございます。

>KeyPreviewプロパティをTrueにしておけば~
KeyPreviewプロパティの件は存じ上げていますが、他との兼ね合いもありテキストボックスのみ実装しておりました。

>それはコーディング上のミスという可能性が高いです
 確かに依然他の物を作る際にフォーム上で同じようなことをしようと試みたところで来ていたと思うので、(1)~(3)全て確認してみたいと思います。
e.KeyCharの部分も改善し、また投稿したいと思います。
投稿者 (削除されました)  () 投稿日時 2022/5/24 09:05:03
(削除されました)
投稿者   (学生) 投稿日時 2022/5/24 10:27:14
入力制限のKeyPressイベントのところと、e.KeyCharの部分は解決いたしました。

追加の質問なのですが、数字のみの入力制限は以下のように記載し実装しております。

 If (e.KeyChar < "0"c OrElse "9"c < e.KeyChar) AndAlso e.KeyChar <> ControlChars.Back Then

            e.Handled = True


 End If

全角文字のみ半角カナのみという風に入力制限したい場合はどのようにコーディングすればよりのでしょうか?
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2022/5/24 12:47:42
たとえば半角で入力してから、あとから「再変換」で部分的に全角化することもできますよね。

辞書登録機能や再変換機能を多用するユーザーのことを鑑みると、
入力時点での制限は、あまりやり過ぎない方が良い場合もあります。

(入力中はあまり強く制限せず、入力後のバリデーション時に
 整形したり警告したりする実装もしばしば見かけます)


> 全角文字のみ半角カナのみ
正規表現を使うか、Like 演算子を使うか、Char 型の範囲指定とか…ですかね。

If Not TextBox1.Text Like "*[!ヲ-゚]*" Then
    Label1.Text = "半角カナのみ(または未入力)"
Else
    Label1.Text = "半角カナ以外が含まれている"  '半角の「1」や「a」、半角ハングルなども混入NG 
End If

Dim re As New Regex("^\p{IsBasicLatin}*$")
If re.IsMatch(TextBox1.Text) Then
    Label2.Text = "基本ラテン文字のみ(または未入力)"
Else
    Label2.Text = "基本ラテン以外が含まれている"
End If



さて…定義が難しいのが「全角」。

Unicode の世界だと、全角でも半角でも無い文字があるんですよね。
たとえば「👳🏽‍♂️」とか。

Shift_JIS で扱われていた文字であっても、たとえば「β」や「┏」の
文字幅は文脈依存とされており、ギリシャ語圏だと半角扱いが普通で、
日本語圏だと全角の事が多い(半角の事もある)という。

https://ja.wikipedia.org/wiki/%E6%9D%B1%E3%82%A2%E3%82%B8%E3%82%A2%E3%81%AE%E6%96%87%E5%AD%97%E5%B9%85
https://www.unicode.org/Public/13.0.0/ucd/EastAsianWidth.txt

なので、全角を定義するというよりも、「半角として扱いたい範囲」を先に定めて、
それを含まないものを「全角のみ」と判断する方向で検討してみてください。
投稿者   (学生) 投稿日時 2022/5/24 17:25:53
本当は数字の様にKeyPressイベントで全角文字以外が入力された場合はキャンセルするという風にしたかったのですが、正規表現を使って入力チェックを行うことといたしました。

確かにURL等見たところ全角というのは難しいですね、、

ご回答ありがとうございました!