none
Pressione tasto "Invio" su un Button, cambiare l'evento RRS feed

  • Domanda

  • Ciao a chi legge,

    avrei bisogno di poter far scegliere all'utente, se preme il tasto invio su un pulsante delle opzioni (aprire un nuovo form o passare al controllo successivo, alla risposta di un msgbox), mentre se preme con il mouse il pulsante stesso aprire semplicemente un nuovo form.

    Ho provato a sfruttare l'evento KeyDown del pulsante, con KeyPreview = true sul form, ecco il codice:

    Private Sub Button2_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Button2.KeyUp
            If e.KeyCode = Keys.Enter Then
                If MsgBox("Vuoi Cercare un Cliente o Fornitore?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
                    FrmClientiFornitori.Show()
                Else
                    Me.ClienteFornitoreTextBox.Focus()

                End If
            End If

        End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            FrmClientiFornitori.Show()
        End Sub

    Ma apre sempre il form, come se cliccassi anche alla pressione del tasto invio.

    Allora mi sono scritto il seguente codice per gestire l'evento:

     Private Sub KeyPressEventHandler(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
            Select Case e.KeyChar
                Case Microsoft.VisualBasic.ChrW(Keys.Return)

                    MessageBox.Show("1")
                    e.Handled = True

                Case Else
            End Select
        End Sub

    E ho aggiunto la seguente riga all'evento load del form:

     AddHandler Me.Button2.KeyPress, AddressOf KeyPressEventHandler

    Ma niente, come sopra.

    Probabilmente sbaglio qualcosa, ma non capisco dove, grazie in anticipo.

    Stefano

    sabato 6 settembre 2014 21:06

Risposte

  • Ciao Stefano.

    Il problema è che l'evento Click, in assenza dell'evento MouseDown, viene sollevato sia da Return che dal click del mouse.

    Quindi, risolvi se utilizzi il l'evento Click per il tasto Enter e l'evento MouseDown per il click del mouse.

    Public Class Form1
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            If MsgBox("Vuoi Cercare un Cliente o Fornitore?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
                FrmClientiFornitori.Show()
            Else
                Me.ClienteFornitoreTextBox.Focus()
    
            End If
        End Sub
    
        Private Sub Button1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseDown
            FrmClientiFornitori.Show()
        End Sub
    End Class

    Ciao.


    vibi6


    • Modificato vibi6 sabato 6 settembre 2014 21:59 Refuso nel codice
    • Contrassegnato come risposta Stefano Muzzin domenica 7 settembre 2014 08:35
    sabato 6 settembre 2014 21:59
  • Ciao vibi6, 

    che brutta cosa :) ... perchè se uso il mouse è ovvio che se premo il pulsante voglio far comparire il nuovo form, mentre vorrei avere la possibilità di scegliere se spostare il focus sulla textbox se voglio scrivere manualmente... Ho aggirato il problema utilizzando lo "spazio", ovvero se premo invio apro il form come con click, altrimenti premo spazio e mi sposto sulla textbox:

    Ciao Stefano,

    se vuoi eseguire due procedure diverse a seconda che l'utente prema Return o Click su un Button puoi scrivere :

    Public Class Form1
        Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
            Select Case (keyData)
                Case (Keys.Enter)
                    MessageBox.Show("Return")
                    Return True
                Case Else
                    Return (MyBase.ProcessDialogKey(keyData))
            End Select
    
        End Function
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            MessageBox.Show("Clik")
        End Sub
    End Class

    Metodo Control.ProcessDialogKey

    Ciao


    Renato Marzaro  MVP Visual Basic

    http://community.visual-basic.it/renato


    domenica 7 settembre 2014 09:03
    Moderatore

Tutte le risposte

  • Ciao Stefano.

    Il problema è che l'evento Click, in assenza dell'evento MouseDown, viene sollevato sia da Return che dal click del mouse.

    Quindi, risolvi se utilizzi il l'evento Click per il tasto Enter e l'evento MouseDown per il click del mouse.

    Public Class Form1
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            If MsgBox("Vuoi Cercare un Cliente o Fornitore?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
                FrmClientiFornitori.Show()
            Else
                Me.ClienteFornitoreTextBox.Focus()
    
            End If
        End Sub
    
        Private Sub Button1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseDown
            FrmClientiFornitori.Show()
        End Sub
    End Class

    Ciao.


    vibi6


    • Modificato vibi6 sabato 6 settembre 2014 21:59 Refuso nel codice
    • Contrassegnato come risposta Stefano Muzzin domenica 7 settembre 2014 08:35
    sabato 6 settembre 2014 21:59
  • Aggiungo che, com'è ovvio, la proprietà KeyPreview del Form la puoi lasciare a False.

    vibi6

    sabato 6 settembre 2014 22:02
  • Ciao vibi6, 

    che brutta cosa :) ... perchè se uso il mouse è ovvio che se premo il pulsante voglio far comparire il nuovo form, mentre vorrei avere la possibilità di scegliere se spostare il focus sulla textbox se voglio scrivere manualmente... Ho aggirato il problema utilizzando lo "spazio", ovvero se premo invio apro il form come con click, altrimenti premo spazio e mi sposto sulla textbox:

    Private Sub Button2_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Button2.KeyDown
            If Keys.Space Then
                Me.ClienteFornitoreTextBox.Focus()
            End If
            
        End Sub
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            FrmSelezionaClientiFornitori.Show()
        End Sub

    Grazie 

    Stefano

    domenica 7 settembre 2014 08:41
  • Ciao vibi6, 

    che brutta cosa :) ... perchè se uso il mouse è ovvio che se premo il pulsante voglio far comparire il nuovo form, mentre vorrei avere la possibilità di scegliere se spostare il focus sulla textbox se voglio scrivere manualmente... Ho aggirato il problema utilizzando lo "spazio", ovvero se premo invio apro il form come con click, altrimenti premo spazio e mi sposto sulla textbox:

    Ciao Stefano,

    se vuoi eseguire due procedure diverse a seconda che l'utente prema Return o Click su un Button puoi scrivere :

    Public Class Form1
        Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
            Select Case (keyData)
                Case (Keys.Enter)
                    MessageBox.Show("Return")
                    Return True
                Case Else
                    Return (MyBase.ProcessDialogKey(keyData))
            End Select
    
        End Function
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            MessageBox.Show("Clik")
        End Sub
    End Class

    Metodo Control.ProcessDialogKey

    Ciao


    Renato Marzaro  MVP Visual Basic

    http://community.visual-basic.it/renato


    domenica 7 settembre 2014 09:03
    Moderatore
  • Ciao Renato,

    era quello che volevo fare... Grazie

    Però alla fine mi sono reso conto che è più veloce premere Space che rispondere a un msgbox, grazie davvero.

    Stefano

    domenica 7 settembre 2014 09:08
  • Ciao.

    Forse mi sfugge qualcosa e quindi chiedo scusa in anticipo, ma tu non volevi intercettare il Return per il solo pulsante Button2 ?


    vibi6

    domenica 7 settembre 2014 09:16
  •  Ciao Vibi,

    hai ragione, il codice di Renato fa l'override su ogni msgbox...

    Stefano

    domenica 7 settembre 2014 09:21
  •  Ciao Vibi,

    hai ragione, il codice di Renato fa l'override su ogni msgbox...

    Stefano

    Ciao Stefano,

    perché mi dici ciò ?

    io ho messo una messagebox per farti vedere il regionamento ma puoi scrivere tranquillamente

    Public Class Form1
        Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
            Select Case (keyData)
                Case (Keys.Enter)
                    'MessageBox.Show("Return")
                    Form2.Show()
                    Return True
                Case Else
                    Return (MyBase.ProcessDialogKey(keyData))
            End Select
    
        End Function
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            'MessageBox.Show("Clik")
            Form3.Show()
        End Sub
    End Class

    Ciao


    Renato Marzaro  MVP Visual Basic

    http://community.visual-basic.it/renato

    domenica 7 settembre 2014 10:01
    Moderatore
  • Ciao Renato,

    però se ho un altro pulsante "button5" e voglio fargli fare un'altra cosa alla pressione del tasto invio, fa sempre la stessa...

    Solo che nel frattempo mi sono costruito pure un msgbox personalizzato :) ed ho risolto con la pressione del tasto Space

    Più tardi se ho tempo provo a verificare se riesco a fare qualcosa di generalista, ovvero, ogni pulsante sul form, risponda in maniera diversa alla pressione del tasto invio, spero di essermi spiegato.

    Grazie 

    Stefano

    domenica 7 settembre 2014 10:07
  • Ciao Stefano,

    Ok ora dovrei aver capito.

    una soluzione 'brutta' che mi è venuta in mente mentre ti rispondevo è questa :

    Public Class Form1
        Private Sub Button1Special1_Click(sender As System.Object, e As System.EventArgs) Handles Button1Special1.Click
            If PressEnter = False Then
                Form4.Show()
            Else
                Form2.Show()
            End If
            PressEnter = False
        End Sub
        Private Sub Button2Special1_Click(sender As System.Object, e As System.EventArgs) Handles Button2Special1.Click
            If PressEnter = False Then
                Form5.Show()
            Else
                Form3.Show()
            End If
            PressEnter = False
        End Sub
    End Class

    Public Class Button1Special
        Inherits Button
        Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
            If keyData = Keys.Enter Then
                PressEnter = True
            End If
            Return MyBase.ProcessCmdKey(msg, keyData)
        End Function
    End Class
    Public Class Button2Special
        Inherits Button
        Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
            If keyData = Keys.Enter Then
                PressEnter = True
            End If
            Return MyBase.ProcessCmdKey(msg, keyData)
        End Function
    End Class

    Module Module1
        Public PressEnter As Boolean
    End Module
    

    Ciao


    Renato Marzaro  MVP Visual Basic

    http://community.visual-basic.it/renato

    domenica 7 settembre 2014 12:04
    Moderatore
  • Ciao Renato,

    era quello che mi serviva, spero serva ad altri :)

    Grazie

    Stefano

    domenica 7 settembre 2014 15:26