-
コンボボックスの基本的な使い方として、コンボボックスの項目に文字列を設定し、 選択されている状態を取得する方法などを説明します。
フォーム上にコンボボックスを1個と、ボタンを2個貼り付けます。 その後、フォームロードイベントでコンボボックスの Itemsプロパティ(ObjectCollection) に各種文字列の追加で初期化を行います。
ボタン1クリックイベントでは、コンボボックスの選択値を取得し表示し、 ボタン2クリックイベントでは、コンボボックスの選択を解除します。コンボボックスの基本的な使い方
Public Class frmComboBox '''''' フォームロードイベント ''' Private Sub frmComboBox_Load(sender As Object, e As EventArgs) Handles Me.Load 'コンボボックス初期化 With Me.ComboBox1 .DropDownStyle = ComboBoxStyle.DropDownList .Items.Add("あいうえお") 'ItemsはObjectのコレクション .Items.Add("かきくけこ") .Items.Add("さしすせそ") .Items.Add("たちつてと") .Items.Add("なにぬねの") .Items.Add("はひふへほ") .Items.Add("まみむめも") .Items.Add("やゆよ") End With End Sub '''''' ボタンクリックイベント・選択状態の表示 ''' Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '選択されているIndexの取得 Dim intIdx As Integer = Me.ComboBox1.SelectedIndex '選択されている文字列の取得 Dim strSel As String = CType(Me.ComboBox1.SelectedItem, String) '結果表示 Dim strDsp As String = "Index : " & intIdx.ToString & vbCrLf & "文字列 : " & strSel MsgBox(strDsp, MsgBoxStyle.OkOnly, Me.Text) End Sub '''''' ボタンクリックイベント・選択状態の解除 ''' Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click '選択されている状態を解除 Me.ComboBox1.SelectedIndex = -1 End Sub End Class
結果これを実行しますと、以下の様になります。
ボタン1のクリック時は以下の様になります。ボタン2のクリック時はコンボボックスの選択が解除され何も表示されないはずです。
尚、選択されている項目Index(SelectedIndex)ですが、この値が -1 であることが 未選択状態を表しますので、 -1 の場合には何も処理をしない様にした方が良いと思います。関連する記事
⇒コンボボックスのItemsプロパティにクラスデータを設定する方法(コードと文字列をセットで設定)
⇒ComboBoxの簡単な拡張クラス(枠線色の描画):[WndProc,CreateGraphics,DrawRectangle]
おすすめ本
PR -
以下のページではフォームクラスにフラグを宣言し、フォームActivatedイベントの処理で最初の呼び出しかどうかを判定していました。
このフラグ処理ですが、全てのフォームに宣言するのも手間が掛かりますので、いっそ継承クラスのフォームにしてはと思い テスト的なフォームのクラスを作成してみました。
先ずはフォーム名をfrmOneActiveBaseとして、 ソース内容は上記の「最初のフォームActivatedイベントでの処理」の内容をそのままコピーしてきます。 但し、テキストボックスの処理は削除してあります。
イベントを1個作成し名前をOneActivatedとして宣言します。 このイベントを、初回のフォームActivatedイベントで発生させる様にします。 ソースは以下の様になります。ベースのフォーム処理
Public Class frmOneActiveBase 'イベント宣言 Public Event OneActivated(ByVal sender As Object, ByVal e As EventArgs) 'アクティブフラグ Private mblnActivated As Boolean = False '''''' フォームアクティブイベント ''' Private Sub frmOneActiveBase_Activated(sender As Object, e As EventArgs) Handles Me.Activated 'アクティブフラグOFF?? If Me.mblnActivated = False Then 'フラグON Me.mblnActivated = True 'イベント発生 RaiseEvent OneActivated(Me, New EventArgs) End If End Sub '''''' フォームロードイベント ''' Private Sub frmOneActiveBase_Load(sender As Object, e As EventArgs) Handles Me.Load Me.mblnActivated = False End Sub End Classここで一旦ビルド作業を行います。 その後、このfrmOneActiveBaseフォームを継承するフォームを作成してみます。
メインメニューの「プロジェクト」⇒「新しい項目の追加」を選択し、以下の表示になったら 左の「Windows Fomrs」を選択後「継承されたフォーム」を選択し、フォーム名をfrmOneActiveとします。
その後「継承ピッカー」の選択になりますので、先ほどの「frmOneActiveBase」を選択しますと以下の様な表示なります。
frmOneActiveのフォームが以下の様に表示されます。
frmOneActiveのフォームが表示されたら、1個のテキストボックスを貼付け、 複数行許可を画面右のプロパティウインドウから行います。
ここでfrmOneActiveフォームのソースを表示させ、 さらに、「frmOneActive(アクティブ)」から「OneActivated」イベント探して、指定します。そこで、以下の様にソースを記述します。
Public Class frmOneActive Private Sub frmOneActive_OneActivated(sender As Object, e As EventArgs) Handles Me.OneActivated 'テキストボックに時刻表示 Me.TextBox1.Text &= "Activated..." & Now.ToString("hh:mm:ss") & vbCrLf End Sub End Class
これでフォームのActivatedイベントでフラグ処理を行わずとも、このOneActivatedイベントの中で処理が可能となります。関連する記事
⇒フォームの位置設定を行う処理 :[Screen.PrimaryScreen.WorkingArea]
⇒フォームクラスにプロパティ宣言し外からアクセスする方法
⇒親フォームのコントロールを子フォームからアクセスする方法
⇒フォームが閉じるのをキャンセルする方法:[FormClosingEventArgs,Cancel]
⇒フォームの表示をモジュールのMain関数から行う(エントリポイントの変更)
⇒フォームがKeyDownなどのキーイベントを受取り、ファンクションキー処理をする
⇒最初のフォームActivatedイベントでの処理(1回のみしか処理しない様にする)
⇒初回のフォームActivatedイベント発生させるフォーム継承について
-
フォームが表示されて初めてアクティブになった時に行いたい処理が在る場合、 以下のソースの様にActivatedイベント時に処理を記述します。
フォーム上に1個のテキストボックスを貼付け、そのテキストボックスを複数行入力許可とします。
そして、Activatedイベント時に現在の時刻を表示します。 ソースは以下の通りです。フォームのActivatedイベントでの処理
Public Class frmActive '''''' フォームアクティブイベント ''' Private Sub frmActive_Activated(sender As Object, e As EventArgs) Handles Me.Activated 'テキストボックに時刻表示 Me.TextBox1.Text &= "Activated..." & Now.ToString("hh:mm:ss") & vbCrLf End Sub '''''' フォームロードイベント ''' Private Sub frmActive_Load(sender As Object, e As EventArgs) Handles Me.Load 'テキストボックスを複数行許可 Me.TextBox1.Multiline = True Me.TextBox1.Height = 200 End Sub End Classこれを実行すると以下の様な表示になります。
上手く動いたかに見えますが、このフォームから別のプログラムなどをアクティブにしてから このプログラムを再度アクティブにすることを繰り返すと以下の様な表示になります。 (日付の表示がどんどん増えていきます)
これは問題です。何が悪いのかと言えば、Activatedイベントは自分自身のフォームが非アクティブから アクティブに変わった時に必ず発生するからです。 プログラムが起動し、最初のActivatedイベントかどうかはフラグを使うしかない様です。 そこで、プログラムを以下の様に変更します。フォームのActivatedイベントでの処理その2
Public Class frmActive 'アクティブフラグ Private mblnActivated As Boolean = False '''''' フォームアクティブイベント ''' Private Sub frmActive_Activated(sender As Object, e As EventArgs) Handles Me.Activated 'アクティブフラグOFF?? If Me.mblnActivated = False Then 'フラグON Me.mblnActivated = True 'テキストボックに時刻表示 Me.TextBox1.Text &= "Activated..." & Now.ToString("hh:mm:ss") & vbCrLf End If End Sub '''''' フォームロードイベント ''' Private Sub frmActive_Load(sender As Object, e As EventArgs) Handles Me.Load 'テキストボックスを複数行許可 Me.TextBox1.Multiline = True Me.TextBox1.Height = 200 'アクティブフラグOFF(くどいですが) Me.mblnActivated = False End Sub End Class
上記のソースではアクティブになったフラグをフォームのローカル変数として宣言し、 Activatedイベント時にそのフラグをみてOFFだったら、フラグをONして二度と時刻表示の処理を しない様にしています。
これで何とかうまくいくようになりました。関連する記事
⇒フォームの位置設定を行う処理 :[Screen.PrimaryScreen.WorkingArea]
⇒フォームクラスにプロパティ宣言し外からアクセスする方法
⇒親フォームのコントロールを子フォームからアクセスする方法
⇒フォームが閉じるのをキャンセルする方法:[FormClosingEventArgs,Cancel]
⇒フォームの表示をモジュールのMain関数から行う(エントリポイントの変更)
⇒フォームがKeyDownなどのキーイベントを受取り、ファンクションキー処理をする
⇒最初のフォームActivatedイベントでの処理(1回のみしか処理しない様にする)
⇒初回のフォームActivatedイベント発生させるフォーム継承について
-
フォーム上のコントロールがアクティブである場合、キー入力があった時にそのコントロールにキーイベントが発生します。 そのコントロールのキーイベントが発生する前に何か処理を行いたい場合、 フォームの KeyPreviewプロパティをTrueに設定すると、フォームのキーイベントが先に発生します。 このイベント処理で、ファンクションキー等の処理が行えます。
例として、ファンクションキー押下でボタンクリックを行う処理を示します。 この処理ですが、ボタンをマウスでクリックする時と同じことをファンクションキー押下で行えます。
良くあるプログラムで、画面の下にボタンを12個並べて、 ボタンキャプションにファンクションキー名を表示しているあれです。 実行画面は以下の様になります。
以下のソースを見て下さい。 フォームのKeyDownイベントで各キーコードの処理を行っています。
ここで注意するのは e.Handled = True の部分です。 この処理でフォームのKeyDownイベント以降に、その他のコントロールにKeyDownイベント発生を抑止しています。
「F10」などではシステムの予約された処理があるので、それを抑止するためです。フォームのKeyDownイベントでのファンクションキー処理
Public Class frmFunc '''''' フォームロードイベント ''' Private Sub frmFunc_Load(sender As Object, e As EventArgs) Handles MyBase.Load 'フォームが先にキーを受け取る設定 Me.KeyPreview = True End Sub '''''' フォームKeyDownイベント ''' Private Sub frmFunc_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown 'キーコードにより処理する Select Case e.KeyCode Case Keys.F1 '「F1:キー」 If Me.Button1.Enabled = True Then '取りあえずボタン許可チェック Me.Button1.Focus() 'フォーカスセット Me.Button1.PerformClick() 'ボタン1クリック実行 End If e.Handled = True '他にKeyDownイベントを発生させない Case Keys.F2 '「F2:キー」 If Me.Button2.Enabled = True Then '取りあえずボタン許可チェック Me.Button2.Focus() 'フォーカスセット Me.Button2.PerformClick() 'ボタン1クリック実行 End If e.Handled = True Case Keys.F3 '「F3:キー」 e.Handled = True Case Keys.F10 '「F10:キー」 e.Handled = True End Select End Sub '''''' ボタン1クリックイベント ''' Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click MsgBox("Button1_Click", MsgBoxStyle.OkOnly, Me.Text) End Sub '''''' ボタン2クリックイベント ''' Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click MsgBox("Button2_Click", MsgBoxStyle.OkOnly, Me.Text) End Sub End Class
関連する記事
⇒フォームクラスにプロパティ宣言し外からアクセスする方法
⇒最初のフォームActivatedイベントでの処理(1回のみしか処理しない様にする)
⇒初回のフォームActivatedイベント発生させるフォーム継承について
⇒フォームクラス生成時に設定値を同時に渡す方法
-
テキストボックスでの入力で、入力される文字を数字のみとしたい場合の方法を示します。
文字の入力を行うとテキストボックスの KeyPress イベントが発生します。 この時に入力された文字をチェックし、数字以外であればその文字を捨てる処理を行います。 尚、 KeyPress イベントでは BackSpaceキー入力の場合も発生しますので、 このキーは有効にする必要があります。KeyPress イベントで数字チェックを行う
Public Class frmTextBox Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress 'キーが [0]~[9] または [BackSpace] 以外の場合イベントをキャンセル If Not (("0"c <= e.KeyChar And e.KeyChar <= "9"c) Or e.KeyChar = ControlChars.Back) Then 'コントロールの既定の処理を省略する場合は true e.Handled = True End If End Sub Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown '[Delete] キーを無効にする場合 If e.KeyCode = Keys.Delete Then e.Handled = True End If End Sub End ClassBackSpaceキーなどの制御用のキーは、 KeyPress イベントが発生しません。 そのため、KeyDown イベントでキーコードによりそれぞれの処理を行います。
(上のプログラムでは、Deleteキーを無効にしています。)
KeyPress イベントの処理でほぼ良いのですが、一つ問題があります。 それは、クリップボードからのコピペを行う場合にはKeyPress イベントが発生しないので、 対応を行わないと数字以外でも貼り付けられてしまいます。
テキストボックスのイベントには、クリップボードからの貼り付け時のイベントが在りませんので、 テキストボックスの大元のウインドウ・メッセージ処理の中でそれを行う必要があります。
普通にテキストボックスをフォームに張り付ける場合には、 ウインドウ・メッセージ処理を変更することはできません。 テキストボックスを継承したクラスの中でウインドウ・メッセージ処理を オーバーライドすることで可能になります。
以下にそのテキストボックスを拡張したクラスのソースを示します。KeyPress イベントで数字チェックを行う
'''
''' 数字とバックスペース以外の入力を無効にしたTextBox ''' Public Class ClsNumTextBox Inherits TextBox 'クリップボード貼付メッセージ Const WM_PASTE As Integer = &H302 '''''' WndProc メソッド (override) ''' ''' <param name="m">メッセージ</param> Protected Overrides Sub WndProc(ByRef m As Message) Select Case m.Msg Case WM_PASTE Dim iDataObj As IDataObject = Clipboard.GetDataObject() 'クリップボードの中身があるか、かつ文字列に変換できるか?? If (iDataObj IsNot Nothing) And (iDataObj.GetDataPresent(DataFormats.Text) = True) Then '文字列に変換 Dim strClip As String = DirectCast(iDataObj.GetData(DataFormats.Text), String) '文字列が数字のみか調べる If Me.ChkClipString(strClip) = False Then 'エラーの場合はここで抜ける Return End If End If End Select 'メッセージのデフォルト処理を呼出す MyBase.WndProc(m) End Sub '''''' コンストラクタ ''' Public Sub New() MyBase.New() 'IMEを無効にする MyBase.ImeMode = ImeMode.Disable End Sub '''''' KeyPressイベントの処理 ''' Protected Overrides Sub OnKeyPress(e As KeyPressEventArgs) MyBase.OnKeyPress(e) 'キーが [0]~[9] または [BackSpace] 以外の場合イベントをキャンセル If Not (("0"c <= e.KeyChar And e.KeyChar <= "9"c) Or e.KeyChar = ControlChars.Back) Then e.Handled = True End If End Sub '''''' 文字列のチェック関数 ''' ''' <param name="strClip">指定文字列</param> '''True:OK, False:NG Private Function ChkClipString(ByVal strClip As String) As Boolean ChkClipString = False If System.Text.RegularExpressions.Regex.IsMatch(strClip, "^[0-9]+$") Then Return True End If End Function End Classこのソースを別のファイルで作成し、一度コンパイルします。 そうすると、ツールボックスの中に ClsNumTextBox が現れますので、 以下の様にこれをフォーム上に貼り付けます。
結果これを実行しますと、以下の様になります。 クリップボードからの貼り付けで、数字以外は表示されないはずです。
関連する記事
⇒テキストボックスの入力を数字のみにする方法その2(電卓の様な入力)
⇒テキストボックス拡張クラスにプロパティを追加する方法
⇒フォーム上のコントロールで[Enter]キー押下で次のコントロールにフォーカス移動する
⇒フォーム上のコントロールのイベント処理の一括関連付け:[AddHandler,DirectCast]
⇒コントロールの同じイベント処理に複数の関連付けをテスト:[AddHandler,DirectCast]
⇒テキストボックスの Leave イベントでのエラー処理でフォーカス強制移動する方法について