none
Tabキーのイベントの取得 RRS feed

  • 質問

  • フォームに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 = True

            txtCMoney1.Text = Format(CInt(Trim(txtCMoney1.Text)), "###,###,###")
                     totalImoney() ’トータル計算及び合計表示

                     txtIMoney2.Select()

                    Case Else
                    e.Handled = True
            End Select
        End Sub

     

    Tabキーを押すと上記の処理をしないで、次のTextBoxに移動してしまいます。(KeyPressではTabイベントは感知しないのでKeyDownで処理内容を変更してテストしたのですがTabイベントを感知することができませんでした)

    Tabキーで次に移動するのはいいのですが、TextBox内容の表示(3桁ごとの,)及び合計計算ができません。

     

    Tabキーを無効にする方法若しくは、Tabキーのイベント発生を捕らえる方法があればご指導をお願いします。

    2008年4月13日 7:27

回答

  •  田舎の爺さんこんばんは

     Tabキーによるフォーカス移動の機能を活かすのであれば、Validatedイベントが使えるのではないでしょうか。

     

     参照URL( Visual Basic 中学校):

    http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard23.htm

    http://homepage1.nifty.com/rucio/main/main.htm

     

    2008年4月13日 10:10
  •  田舎の爺 さんからの引用

    Tabキーを押すと上記の処理をしないで、次のTextBoxに移動してしまいます。(KeyPressではTabイベントは感知しないのでKeyDownで処理内容を変更してテストしたのですがTabイベントを感知することができませんでした)

    Tabキーで次に移動するのはいいのですが、TextBox内容の表示(3桁ごとの,)及び合計計算ができません。

    0~9を押すとその時点で次のテキストボックスにフォーカスを移動するようなコードに見受けられました。

    一桁しか入力しないのですか?

     

     田舎の爺 さんからの引用

    Tabキーを無効にする方法若しくは、Tabキーのイベント発生を捕らえる方法があればご指導をお願いします。

    やりたいことを明確にしておくべきでしょう。

    値の検証がしたいのであれば、Validatingでしょうか。

    ただ、フォーカス移動を細かく制御すると変な不具合を生む可能性があるのでお薦めはしません。

     

    また、Tabキーでフォーカス移動を完全にできなくしたいのであれば、全てのコントロールのTabStopプロパティをfalseにするというのも手かもしれませんね。

    2008年4月13日 10:21
    モデレータ
  • Tabキーはイベント発生の前にプリプロセスで処理されてしまい、次のコントロールにフォーカスが移動してしまいますので、プリプロセスをカスタマイズする必要があります。

    ただ、Tabキーの処理を変更すると、Windowsの標準の動作と異なってしまいますので、慎重に検討されることをお勧めします。

     

    Windowsアプリケーションで方向キーなどの特殊キーを処理するには?
    http://www.atmarkit.co.jp/fdotnet/dotnettips/241windlgkey/windlgkey.html

    2008年4月13日 13:17
    モデレータ
  •  田舎の爺 さんからの引用

    記載のコードですが、「Enter」キーが押されたら、次のテキストボックスへフォーカスを移動するようにしています。)

    失礼しました。インデントの関係で見落としていました。

     

     田舎の爺 さんからの引用

    Tabキーが押されると、記載コードがまったく実行されなく、次のテキストボックスへ移動してしまうのを防御したかったのです。

    マウスでのフォーカス遷移は想定外?

    Validatingイベントであれば、マウスであろうと、キーボードであろうと検証されるはずです。

    しかし、構成を美味く考えておかないと、ダイアログをキャンセルすることすらできない使い勝手の悪いアプリになるリスクがあります。

    2008年4月14日 14:02
    モデレータ
  • 簡単なコードを書いてみました。

     

    ┌────────────┐
    │┌──────────┐│
    ││[GroupBox]groupInput││
    ││┌────────┐││
    │││TextBox1    │││
    ││└────────┘││
    ││┌────────┐││
    │││TextBox2    │││
    ││└────────┘││
    ││┌────────┐││
    │││TextBox3    │││
    ││└────────┘││
    │└──────────┘│
    │┌──────────┐│
    ││txtSummary     ││
    │└──────────┘│
    └────────────┘
    上記のようなフォームを作成する必要があります。
    TextBox1~TextBox3に値を入力しますと、txtSummaryに合計値を表示する処理を行っています。
     
     

    >Tabキーが押されると、記載コードがまったく実行されなく、次のテキストボックスへ移動してしまうのを防御したかったのです。

    >Validatingを使ってよって見たいと思います。

     
    あ、コードを作ってから気づきました。
    移動を防ぐ必要があるのでしょうか?
    下記のサンプルではその処理を入れていないので、参考になるかどうか・・・
     
     
     
    Code Snippet
    Public 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.Zero
            For 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
            Next
            Return 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 Sub
        Private Sub TextBox_Enter(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim num As Decimal = Decimal.Zero
            If sender.GetType() Is GetType(TextBox) Then
                Dim txt As TextBox = CType(sender, TextBox)
                txt.Text = txt.Text.Replace(",", "")
            End If
        End Sub
        Private Sub TextBox_Leave(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim num As Decimal = Decimal.Zero
            If 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 Sub
        Private Sub TextBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
            Me.txtSummary.Text = Me.CalcInputTextBoxs().ToString("N0")
        End Sub
    End Class

     

     

    2008年4月14日 23:29

すべての返信

  •  田舎の爺さんこんばんは

     Tabキーによるフォーカス移動の機能を活かすのであれば、Validatedイベントが使えるのではないでしょうか。

     

     参照URL( Visual Basic 中学校):

    http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard23.htm

    http://homepage1.nifty.com/rucio/main/main.htm

     

    2008年4月13日 10:10
  •  田舎の爺 さんからの引用

    Tabキーを押すと上記の処理をしないで、次のTextBoxに移動してしまいます。(KeyPressではTabイベントは感知しないのでKeyDownで処理内容を変更してテストしたのですがTabイベントを感知することができませんでした)

    Tabキーで次に移動するのはいいのですが、TextBox内容の表示(3桁ごとの,)及び合計計算ができません。

    0~9を押すとその時点で次のテキストボックスにフォーカスを移動するようなコードに見受けられました。

    一桁しか入力しないのですか?

     

     田舎の爺 さんからの引用

    Tabキーを無効にする方法若しくは、Tabキーのイベント発生を捕らえる方法があればご指導をお願いします。

    やりたいことを明確にしておくべきでしょう。

    値の検証がしたいのであれば、Validatingでしょうか。

    ただ、フォーカス移動を細かく制御すると変な不具合を生む可能性があるのでお薦めはしません。

     

    また、Tabキーでフォーカス移動を完全にできなくしたいのであれば、全てのコントロールのTabStopプロパティをfalseにするというのも手かもしれませんね。

    2008年4月13日 10:21
    モデレータ
  • Tabキーはイベント発生の前にプリプロセスで処理されてしまい、次のコントロールにフォーカスが移動してしまいますので、プリプロセスをカスタマイズする必要があります。

    ただ、Tabキーの処理を変更すると、Windowsの標準の動作と異なってしまいますので、慎重に検討されることをお勧めします。

     

    Windowsアプリケーションで方向キーなどの特殊キーを処理するには?
    http://www.atmarkit.co.jp/fdotnet/dotnettips/241windlgkey/windlgkey.html

    2008年4月13日 13:17
    モデレータ
  • 三輪の牛さん

    ありがとうございました。

    色々とやって見たいと思います。

    2008年4月13日 23:26
  • Azuleanさん

     

    記載のコードですが、「Enter」キーが押されたら、次のテキストボックスへフォーカスを移動するようにしています。)

    やりたいことは、入力した値の表示を、3桁ごとに 「、」 を入れ、合計計算をすることです。

    Tabキーが押されると、記載コードがまったく実行されなく、次のテキストボックスへ移動してしまうのを防御したかったのです。

    Validatingを使ってよって見たいと思います。

     

    ありがとうございました。

     

     

     

    2008年4月13日 23:38
  • trapemiyaさん

     

    ありがとうございました。

     

     

    2008年4月13日 23:42
  •  田舎の爺 さんからの引用

    記載のコードですが、「Enter」キーが押されたら、次のテキストボックスへフォーカスを移動するようにしています。)

    失礼しました。インデントの関係で見落としていました。

     

     田舎の爺 さんからの引用

    Tabキーが押されると、記載コードがまったく実行されなく、次のテキストボックスへ移動してしまうのを防御したかったのです。

    マウスでのフォーカス遷移は想定外?

    Validatingイベントであれば、マウスであろうと、キーボードであろうと検証されるはずです。

    しかし、構成を美味く考えておかないと、ダイアログをキャンセルすることすらできない使い勝手の悪いアプリになるリスクがあります。

    2008年4月14日 14:02
    モデレータ
  • 簡単なコードを書いてみました。

     

    ┌────────────┐
    │┌──────────┐│
    ││[GroupBox]groupInput││
    ││┌────────┐││
    │││TextBox1    │││
    ││└────────┘││
    ││┌────────┐││
    │││TextBox2    │││
    ││└────────┘││
    ││┌────────┐││
    │││TextBox3    │││
    ││└────────┘││
    │└──────────┘│
    │┌──────────┐│
    ││txtSummary     ││
    │└──────────┘│
    └────────────┘
    上記のようなフォームを作成する必要があります。
    TextBox1~TextBox3に値を入力しますと、txtSummaryに合計値を表示する処理を行っています。
     
     

    >Tabキーが押されると、記載コードがまったく実行されなく、次のテキストボックスへ移動してしまうのを防御したかったのです。

    >Validatingを使ってよって見たいと思います。

     
    あ、コードを作ってから気づきました。
    移動を防ぐ必要があるのでしょうか?
    下記のサンプルではその処理を入れていないので、参考になるかどうか・・・
     
     
     
    Code Snippet
    Public 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.Zero
            For 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
            Next
            Return 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 Sub
        Private Sub TextBox_Enter(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim num As Decimal = Decimal.Zero
            If sender.GetType() Is GetType(TextBox) Then
                Dim txt As TextBox = CType(sender, TextBox)
                txt.Text = txt.Text.Replace(",", "")
            End If
        End Sub
        Private Sub TextBox_Leave(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim num As Decimal = Decimal.Zero
            If 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 Sub
        Private Sub TextBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
            Me.txtSummary.Text = Me.CalcInputTextBoxs().ToString("N0")
        End Sub
    End Class

     

     

    2008年4月14日 23:29
  • みなさんこんにちは、森田です。
    田舎の爺さん、フォーラムのご利用ありがとうございます。


    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 をご覧ください。
    2008年6月3日 9:42