none
keydown for textbox in nested Panels

    Question

  • Hi All

    i've aform with several panels a panels inside panel

    I've also several text Box in Panel at first level,

    textbox in panel at second level and so on

    Now i want to check the keydown for each textbox in the form with a code like this :

     AddHandler TB.KeyDown, AddressOf DownJey

     Private Shared Sub DownKey(sender As Object, e As KeyEventArgs)
            code to control the key
      End Sub

    The question is

    Is there a way to have the list of all text box in the form ?

    Do  i need to write code with several

    FOR EACH C as control in me.controls 

         FOR EACH c1 as control in c.controls 

            ETC ETC 


    The problem is that i dont know at wich panel level i have the texboxs

    Claudio

    Thursday, December 07, 2017 6:05 PM

Answers

  • Here you go, note that GetAll can be placed say in a code module or even made into an extension method but let's keep it simple here.

    Public Class Form2
        Public Function GetAll(ByVal control As Control, ByVal type As Type) As IEnumerable(Of Control)
            Dim controls = control.Controls.Cast(Of Control)()
            Return controls.SelectMany(Function(ctrl) GetAll(ctrl, type)) _
                .Concat(controls).Where(Function(c) c.GetType() Is type)
        End Function
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim tbList As IEnumerable(Of TextBox) = GetAll(Me, GetType(TextBox)).OfType(Of TextBox)
            For Each tb As TextBox In tbList
                AddHandler tb.KeyDown, AddressOf DownKey
            Next
        End Sub
        Private Shared Sub DownKey(sender As Object, e As KeyEventArgs)
            MessageBox.Show(CType(sender, TextBox).Name)
        End Sub
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Marked as answer by Claudio111 Thursday, December 07, 2017 6:31 PM
    Thursday, December 07, 2017 6:19 PM
    Moderator
  • Good to hear the code fit into your code :-)

    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Marked as answer by Claudio111 Thursday, December 07, 2017 6:58 PM
    Thursday, December 07, 2017 6:55 PM
    Moderator
  • You are fine with what I provided, if it works go with it but we could also do the following.

    Create a code module named LanguageExensions, replace it's contents with this.

    Public Module LanguageExtensions
        <Runtime.CompilerServices.Extension()>
        Public Function GetAll(ByVal control As Control, ByVal type As Type) As IEnumerable(Of Control)
            Dim controls = control.Controls.Cast(Of Control)()
            Return controls.SelectMany(Function(ctrl) GetAll(ctrl, type)) _
                .Concat(controls).Where(Function(c) c.GetType() Is type)
        End Function
        <Runtime.CompilerServices.Extension()>
        Public Function AllTextBoxes(ByVal pSender As Control) As IEnumerable(Of TextBox)
            Return GetAll(pSender, GetType(TextBox)).OfType(Of TextBox)
        End Function
    End Module

    Our form is now

    Public Class Form2
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Me.AllTextBoxes.ToList.ForEach(
                Sub(tb)
                    AddHandler tb.KeyDown, AddressOf DownKey
                End Sub)
    
        End Sub
        Private Shared Sub DownKey(sender As Object, e As KeyEventArgs)
            MessageBox.Show(CType(sender, TextBox).Name)
        End Sub
    End Class

    Why??? because with the code module we can also do....

    Public Module LanguageExtensions
        <Runtime.CompilerServices.Extension()>
        Public Function GetAll(ByVal control As Control, ByVal type As Type) As IEnumerable(Of Control)
            Dim controls = control.Controls.Cast(Of Control)()
            Return controls.SelectMany(Function(ctrl) GetAll(ctrl, type)) _
                .Concat(controls).Where(Function(c) c.GetType() Is type)
        End Function
        <Runtime.CompilerServices.Extension()>
        Public Function AllTextBoxes(ByVal pSender As Control) As IEnumerable(Of TextBox)
            Return GetAll(pSender, GetType(TextBox)).OfType(Of TextBox)
        End Function
        <Runtime.CompilerServices.Extension()>
        Public Function AllCheckBoxes(ByVal pSender As Control) As IEnumerable(Of CheckBox)
            Return GetAll(pSender, GetType(CheckBox)).OfType(Of CheckBox)
        End Function
    End Module
    

    Simple example for AllCheckBoxes

    Public Class Form2
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Me.AllCheckBoxes.ToList.ForEach(
                Sub(cb)
                    cb.Checked = True
                End Sub)
    
        End Sub
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Marked as answer by Claudio111 Thursday, December 07, 2017 7:46 PM
    Thursday, December 07, 2017 7:10 PM
    Moderator

All replies

  • Here you go, note that GetAll can be placed say in a code module or even made into an extension method but let's keep it simple here.

    Public Class Form2
        Public Function GetAll(ByVal control As Control, ByVal type As Type) As IEnumerable(Of Control)
            Dim controls = control.Controls.Cast(Of Control)()
            Return controls.SelectMany(Function(ctrl) GetAll(ctrl, type)) _
                .Concat(controls).Where(Function(c) c.GetType() Is type)
        End Function
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim tbList As IEnumerable(Of TextBox) = GetAll(Me, GetType(TextBox)).OfType(Of TextBox)
            For Each tb As TextBox In tbList
                AddHandler tb.KeyDown, AddressOf DownKey
            Next
        End Sub
        Private Shared Sub DownKey(sender As Object, e As KeyEventArgs)
            MessageBox.Show(CType(sender, TextBox).Name)
        End Sub
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Marked as answer by Claudio111 Thursday, December 07, 2017 6:31 PM
    Thursday, December 07, 2017 6:19 PM
    Moderator
  • HI Karen 

    a little complicated but i will study it and use it

    Thank a lot

    Claudio

    Thursday, December 07, 2017 6:31 PM
  • Here is what I validated against, several panels, a group box and TextBox in each container


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Thursday, December 07, 2017 6:34 PM
    Moderator
  • I use it and works perfectly with my code

    Public Sub CkKey(ByVal nform As Form)
            Dim TBList As IEnumerable(Of TextBox) = GetAll(nform, GetType(TextBox)).OfType(Of TextBox)
            For Each TB As TextBox In TBList
                AddHandler TB.KeyDown, AddressOf DownTasto
                MessageBox.Show(TB.Name.ToString)
    
                If TB.Tag = "AN" Then
                    AddHandler TB.KeyPress, AddressOf PressTastoAlfaNumerico
                End If
                If TB.Tag = "NDB" Then
                    AddHandler TB.KeyPress, AddressOf PressTastoNomePerDB
                End If
                If TB.Tag = "NI" Then
                    AddHandler TB.KeyPress, AddressOf PressTastoSoloNumeriInteri
                End If
                If TB.Tag = "ND" Then
                    AddHandler TB.KeyPress, AddressOf PressTastoNumeriDecimali
                End If
                If TB.Tag = "CP" Then
                    AddHandler TB.KeyPress, AddressOf PressTastoSoloCAP
                End If
    
                ' MANCA EMAIL
            Next
    
        End Sub
    
        Private Sub DownTasto(sender As Object, e As KeyEventArgs)
            ' prendi il nome del textbox sul quale si e' premuto un tasto
            Dim TextboxName = sender.name.ToString
    
            If e.KeyCode = Keys.Enter Then e.SuppressKeyPress = True
    
            '  Prendi il nome del form che contiene il TextBox di cui sopra
            NomeFormChiamante = sender.FindForm()
            If e.KeyCode = 13 Then ' tasto invio
                e.Handled = True
                SendKeys.Send("{TAB}") ' simula TAB
            End If
            ' controlla se premuti tasti funzione
            If e.KeyValue >= 112 And e.KeyValue <= 123 Then
                ' chiama la SUB del form chiamante per controllare le azioni sul tasto funzione
                ' premuto sul textbox che ha il focus
    
                NomeFormChiamante.CkFkTextBox(TextboxName, e.KeyData.ToString)
                e.Handled = True
    
            End If
        End Sub
    
    

    Thursday, December 07, 2017 6:53 PM
  • Good to hear the code fit into your code :-)

    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Marked as answer by Claudio111 Thursday, December 07, 2017 6:58 PM
    Thursday, December 07, 2017 6:55 PM
    Moderator
  • Just one question

    which is the difference if i have the above code in  module or in a class.

    Do i need a class ? 

    Thursday, December 07, 2017 6:55 PM
  • You are fine with what I provided, if it works go with it but we could also do the following.

    Create a code module named LanguageExensions, replace it's contents with this.

    Public Module LanguageExtensions
        <Runtime.CompilerServices.Extension()>
        Public Function GetAll(ByVal control As Control, ByVal type As Type) As IEnumerable(Of Control)
            Dim controls = control.Controls.Cast(Of Control)()
            Return controls.SelectMany(Function(ctrl) GetAll(ctrl, type)) _
                .Concat(controls).Where(Function(c) c.GetType() Is type)
        End Function
        <Runtime.CompilerServices.Extension()>
        Public Function AllTextBoxes(ByVal pSender As Control) As IEnumerable(Of TextBox)
            Return GetAll(pSender, GetType(TextBox)).OfType(Of TextBox)
        End Function
    End Module

    Our form is now

    Public Class Form2
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Me.AllTextBoxes.ToList.ForEach(
                Sub(tb)
                    AddHandler tb.KeyDown, AddressOf DownKey
                End Sub)
    
        End Sub
        Private Shared Sub DownKey(sender As Object, e As KeyEventArgs)
            MessageBox.Show(CType(sender, TextBox).Name)
        End Sub
    End Class

    Why??? because with the code module we can also do....

    Public Module LanguageExtensions
        <Runtime.CompilerServices.Extension()>
        Public Function GetAll(ByVal control As Control, ByVal type As Type) As IEnumerable(Of Control)
            Dim controls = control.Controls.Cast(Of Control)()
            Return controls.SelectMany(Function(ctrl) GetAll(ctrl, type)) _
                .Concat(controls).Where(Function(c) c.GetType() Is type)
        End Function
        <Runtime.CompilerServices.Extension()>
        Public Function AllTextBoxes(ByVal pSender As Control) As IEnumerable(Of TextBox)
            Return GetAll(pSender, GetType(TextBox)).OfType(Of TextBox)
        End Function
        <Runtime.CompilerServices.Extension()>
        Public Function AllCheckBoxes(ByVal pSender As Control) As IEnumerable(Of CheckBox)
            Return GetAll(pSender, GetType(CheckBox)).OfType(Of CheckBox)
        End Function
    End Module
    

    Simple example for AllCheckBoxes

    Public Class Form2
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Me.AllCheckBoxes.ToList.ForEach(
                Sub(cb)
                    cb.Checked = True
                End Sub)
    
        End Sub
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Marked as answer by Claudio111 Thursday, December 07, 2017 7:46 PM
    Thursday, December 07, 2017 7:10 PM
    Moderator
  • scuse me Karen i dont understand one thin

    when in the button click event you call AllTextBox you should give a value for psender (in the called Function )

    I dont understand the meaning of Sub(tb) .... end Sub you give to psender

    Can You explain it to me please ! ;-)

    Thursday, December 07, 2017 11:08 PM