トップ回答者
Tabキーのイベントの取得

質問
-
フォームにTextBox1、TextBox2・・・と複数のTextBoxを配置し、TextBoxには数値を入力し入力数値の合計を最後のTextBoxに表示するようにしています。
それぞれのTextBoxのコードは下記のようにしています。
Private Sub txtIMoney1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtIMoney1.KeyPress
Select Case e.KeyChar
Case "0" To "9"
Case Microsoft.VisualBasic.ChrW(13)
e.Handled = TruetxtCMoney1.Text = Format(CInt(Trim(txtCMoney1.Text)), "###,###,###")
totalImoney() ’トータル計算及び合計表示txtIMoney2.Select()
Case Else
e.Handled = True
End Select
End SubTabキーを押すと上記の処理をしないで、次のTextBoxに移動してしまいます。(KeyPressではTabイベントは感知しないのでKeyDownで処理内容を変更してテストしたのですがTabイベントを感知することができませんでした)
Tabキーで次に移動するのはいいのですが、TextBox内容の表示(3桁ごとの,)及び合計計算ができません。
Tabキーを無効にする方法若しくは、Tabキーのイベント発生を捕らえる方法があればご指導をお願いします。
回答
-
田舎の爺さんこんばんは
Tabキーによるフォーカス移動の機能を活かすのであれば、Validatedイベントが使えるのではないでしょうか。
参照URL( Visual Basic 中学校):
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard23.htm
http://homepage1.nifty.com/rucio/main/main.htm
-
田舎の爺 さんからの引用 Tabキーを押すと上記の処理をしないで、次のTextBoxに移動してしまいます。(KeyPressではTabイベントは感知しないのでKeyDownで処理内容を変更してテストしたのですがTabイベントを感知することができませんでした)
Tabキーで次に移動するのはいいのですが、TextBox内容の表示(3桁ごとの,)及び合計計算ができません。
0~9を押すとその時点で次のテキストボックスにフォーカスを移動するようなコードに見受けられました。
一桁しか入力しないのですか?
田舎の爺 さんからの引用 Tabキーを無効にする方法若しくは、Tabキーのイベント発生を捕らえる方法があればご指導をお願いします。
やりたいことを明確にしておくべきでしょう。
値の検証がしたいのであれば、Validatingでしょうか。
ただ、フォーカス移動を細かく制御すると変な不具合を生む可能性があるのでお薦めはしません。
また、Tabキーでフォーカス移動を完全にできなくしたいのであれば、全てのコントロールのTabStopプロパティをfalseにするというのも手かもしれませんね。
-
Tabキーはイベント発生の前にプリプロセスで処理されてしまい、次のコントロールにフォーカスが移動してしまいますので、プリプロセスをカスタマイズする必要があります。
ただ、Tabキーの処理を変更すると、Windowsの標準の動作と異なってしまいますので、慎重に検討されることをお勧めします。
Windowsアプリケーションで方向キーなどの特殊キーを処理するには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/241windlgkey/windlgkey.html -
田舎の爺 さんからの引用 記載のコードですが、「Enter」キーが押されたら、次のテキストボックスへフォーカスを移動するようにしています。)
失礼しました。インデントの関係で見落としていました。
田舎の爺 さんからの引用 Tabキーが押されると、記載コードがまったく実行されなく、次のテキストボックスへ移動してしまうのを防御したかったのです。
マウスでのフォーカス遷移は想定外?
Validatingイベントであれば、マウスであろうと、キーボードであろうと検証されるはずです。
しかし、構成を美味く考えておかないと、ダイアログをキャンセルすることすらできない使い勝手の悪いアプリになるリスクがあります。
-
簡単なコードを書いてみました。
┌────────────┐
│┌──────────┐│
││[GroupBox]groupInput││
││┌────────┐││
│││TextBox1 │││
││└────────┘││
││┌────────┐││
│││TextBox2 │││
││└────────┘││
││┌────────┐││
│││TextBox3 │││
││└────────┘││
│└──────────┘│
│┌──────────┐│
││txtSummary ││
│└──────────┘│
└────────────┘上記のようなフォームを作成する必要があります。TextBox1~TextBox3に値を入力しますと、txtSummaryに合計値を表示する処理を行っています。>Tabキーが押されると、記載コードがまったく実行されなく、次のテキストボックスへ移動してしまうのを防御したかったのです。
>Validatingを使ってよって見たいと思います。
あ、コードを作ってから気づきました。移動を防ぐ必要があるのでしょうか?下記のサンプルではその処理を入れていないので、参考になるかどうか・・・Code SnippetPublic Class Form1''' <summary>
''' コンストラクタ
''' </summary>
''' <remarks></remarks>
Public Sub New()' この呼び出しは、Windows フォーム デザイナで必要です。
InitializeComponent()' InitializeComponent() 呼び出しの後で初期化を追加します。
For Each cont As Control In Me.groupInput.Controls
AddHandler cont.Enter, AddressOf Me.TextBox_Enter
AddHandler cont.Leave, AddressOf Me.TextBox_Leave
AddHandler cont.TextChanged, AddressOf Me.TextBox_TextChanged
Next
End Sub''' <summary>
''' groupInput内のテキストボックス全てをサマリーした結果を返す。
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function CalcInputTextBoxs() As Decimal
Dim num As Decimal = Decimal.Zero
Dim sum As Decimal = Decimal.ZeroFor Each cont As Control In Me.groupInput.Controls
If cont.GetType() Is GetType(TextBox) Then
If Decimal.TryParse(cont.Text, num) Then
sum += num
End If
End If
NextReturn sum
End Function''' <summary>
''' キーダウンイベント
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Enter Then
Me.SelectNextControl(Me.ActiveControl, Not (e.Shift), True, True, True)
End If
End SubPrivate Sub TextBox_Enter(ByVal sender As Object, ByVal e As System.EventArgs)
Dim num As Decimal = Decimal.ZeroIf sender.GetType() Is GetType(TextBox) Then
Dim txt As TextBox = CType(sender, TextBox)
txt.Text = txt.Text.Replace(",", "")
End If
End SubPrivate Sub TextBox_Leave(ByVal sender As Object, ByVal e As System.EventArgs)
Dim num As Decimal = Decimal.ZeroIf sender.GetType() Is GetType(TextBox) Then
Dim txt As TextBox = CType(sender, TextBox)
If Decimal.TryParse(txt.Text, num) Then
txt.Text = num.ToString("N0")
End If
End If
End SubPrivate Sub TextBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Me.txtSummary.Text = Me.CalcInputTextBoxs().ToString("N0")
End Sub
End Class
すべての返信
-
田舎の爺さんこんばんは
Tabキーによるフォーカス移動の機能を活かすのであれば、Validatedイベントが使えるのではないでしょうか。
参照URL( Visual Basic 中学校):
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard23.htm
http://homepage1.nifty.com/rucio/main/main.htm
-
田舎の爺 さんからの引用 Tabキーを押すと上記の処理をしないで、次のTextBoxに移動してしまいます。(KeyPressではTabイベントは感知しないのでKeyDownで処理内容を変更してテストしたのですがTabイベントを感知することができませんでした)
Tabキーで次に移動するのはいいのですが、TextBox内容の表示(3桁ごとの,)及び合計計算ができません。
0~9を押すとその時点で次のテキストボックスにフォーカスを移動するようなコードに見受けられました。
一桁しか入力しないのですか?
田舎の爺 さんからの引用 Tabキーを無効にする方法若しくは、Tabキーのイベント発生を捕らえる方法があればご指導をお願いします。
やりたいことを明確にしておくべきでしょう。
値の検証がしたいのであれば、Validatingでしょうか。
ただ、フォーカス移動を細かく制御すると変な不具合を生む可能性があるのでお薦めはしません。
また、Tabキーでフォーカス移動を完全にできなくしたいのであれば、全てのコントロールのTabStopプロパティをfalseにするというのも手かもしれませんね。
-
Tabキーはイベント発生の前にプリプロセスで処理されてしまい、次のコントロールにフォーカスが移動してしまいますので、プリプロセスをカスタマイズする必要があります。
ただ、Tabキーの処理を変更すると、Windowsの標準の動作と異なってしまいますので、慎重に検討されることをお勧めします。
Windowsアプリケーションで方向キーなどの特殊キーを処理するには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/241windlgkey/windlgkey.html -
田舎の爺 さんからの引用 記載のコードですが、「Enter」キーが押されたら、次のテキストボックスへフォーカスを移動するようにしています。)
失礼しました。インデントの関係で見落としていました。
田舎の爺 さんからの引用 Tabキーが押されると、記載コードがまったく実行されなく、次のテキストボックスへ移動してしまうのを防御したかったのです。
マウスでのフォーカス遷移は想定外?
Validatingイベントであれば、マウスであろうと、キーボードであろうと検証されるはずです。
しかし、構成を美味く考えておかないと、ダイアログをキャンセルすることすらできない使い勝手の悪いアプリになるリスクがあります。
-
簡単なコードを書いてみました。
┌────────────┐
│┌──────────┐│
││[GroupBox]groupInput││
││┌────────┐││
│││TextBox1 │││
││└────────┘││
││┌────────┐││
│││TextBox2 │││
││└────────┘││
││┌────────┐││
│││TextBox3 │││
││└────────┘││
│└──────────┘│
│┌──────────┐│
││txtSummary ││
│└──────────┘│
└────────────┘上記のようなフォームを作成する必要があります。TextBox1~TextBox3に値を入力しますと、txtSummaryに合計値を表示する処理を行っています。>Tabキーが押されると、記載コードがまったく実行されなく、次のテキストボックスへ移動してしまうのを防御したかったのです。
>Validatingを使ってよって見たいと思います。
あ、コードを作ってから気づきました。移動を防ぐ必要があるのでしょうか?下記のサンプルではその処理を入れていないので、参考になるかどうか・・・Code SnippetPublic Class Form1''' <summary>
''' コンストラクタ
''' </summary>
''' <remarks></remarks>
Public Sub New()' この呼び出しは、Windows フォーム デザイナで必要です。
InitializeComponent()' InitializeComponent() 呼び出しの後で初期化を追加します。
For Each cont As Control In Me.groupInput.Controls
AddHandler cont.Enter, AddressOf Me.TextBox_Enter
AddHandler cont.Leave, AddressOf Me.TextBox_Leave
AddHandler cont.TextChanged, AddressOf Me.TextBox_TextChanged
Next
End Sub''' <summary>
''' groupInput内のテキストボックス全てをサマリーした結果を返す。
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function CalcInputTextBoxs() As Decimal
Dim num As Decimal = Decimal.Zero
Dim sum As Decimal = Decimal.ZeroFor Each cont As Control In Me.groupInput.Controls
If cont.GetType() Is GetType(TextBox) Then
If Decimal.TryParse(cont.Text, num) Then
sum += num
End If
End If
NextReturn sum
End Function''' <summary>
''' キーダウンイベント
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Enter Then
Me.SelectNextControl(Me.ActiveControl, Not (e.Shift), True, True, True)
End If
End SubPrivate Sub TextBox_Enter(ByVal sender As Object, ByVal e As System.EventArgs)
Dim num As Decimal = Decimal.ZeroIf sender.GetType() Is GetType(TextBox) Then
Dim txt As TextBox = CType(sender, TextBox)
txt.Text = txt.Text.Replace(",", "")
End If
End SubPrivate Sub TextBox_Leave(ByVal sender As Object, ByVal e As System.EventArgs)
Dim num As Decimal = Decimal.ZeroIf sender.GetType() Is GetType(TextBox) Then
Dim txt As TextBox = CType(sender, TextBox)
If Decimal.TryParse(txt.Text, num) Then
txt.Text = num.ToString("N0")
End If
End If
End SubPrivate Sub TextBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Me.txtSummary.Text = Me.CalcInputTextBoxs().ToString("N0")
End Sub
End Class -
みなさんこんにちは、森田です。
田舎の爺さん、フォーラムのご利用ありがとうございます。
Validatingイベントを用いれば、キーボードやマウス等のフォーカス遷移を
一意で取得できるので便利だと思います。個人的には、TextBox毎の各Validatingイベントを1つのイベント ハンドラで処理することをお勧めします!
このようにすると、処理も共通化でき、ソースもシンプルになって可読性もよくなると思いますので。方法 : Windows フォームの 1 つのイベント ハンドラに複数のイベントを関連付ける
http://msdn.microsoft.com/ja-jp/library/3exstx90.aspxただ、Azuleanさんもご指摘されているように、
予期しないValidatingイベントの発生などには注意をしてくださいね。
回答をくださったみなさんありがとうございました!
みなさんの情報に回答済みチェックを付けさせていただきました。
何らかの権利を許諾するものでもありません。
コミュニティにおけるマイクロソフト社員による発言やコメントは、マイクロソフトの正式な見解またはコメントではありません。
詳しくは http://www.microsoft.com/japan/communities/msp.mspx をご覧ください。