Button.Select Methode löst das ButtonClick-Ereignis aus

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Button.Select Methode löst das ButtonClick-Ereignis aus

    Hallo, ich habe in meiner WIN-Forms Anwendung folgendes Problem: Aus einem Sub soll mittels Button.Select der Button den Focus erhalten, damit mittels Enter-Taste das dahinterliegende Klick-Ereignis ausgeführt werden kann. Erstaunlicherweise wird dies jedoch schon durch das Select ohne weiteres zutun ausgeführt.
    Gibt es dafür eine Erklärung oder Abhilfe?
    Ist es der einzige Button ? Bzw. der erste den du dir erstellt hast ? Dann ist es ganz normal aufgrund des TabIndex.

    Falls du das meinst. Dieser wird beim ersten Objekt standardmäßig auf 0 gesetzt.

    Js1101 schrieb:

    Button den Focus erhalten, damit mittels Enter-Taste das dahinterliegende Klick-Ereignis ausgeführt werden kann. Erstaunlicherweise wird dies jedoch schon durch das Select ohne weiteres zutun ausgeführt.
    Glaub ich nicht.
    Prüf das nochmal genau nach - da muss noch iwas anneres mit hineinspielen.
    Kannst du uns den Teil deines Codes zeigen? Ich würde mir das gerne anschauen. Ich habe zwar noch nie die Select Funktion gebraucht, aber vielleicht hilft mein Wissen.
    Wenn ich eine Frage stelle, habe ich sie bereits gegooglet. Ja, es kommt vor, dass ich die Antwort übersehe. Ja, es kommt vor, dass ich sie nicht verstehe. Deshalb bin ich hier. Wenn dies eure Frage war, dann antwortet bitte nicht. Es stiehlt sämtliche Motivation.
    @Js1101 Willkommen im Forum. :thumbup:
    Mach mal ein neues Projekt mit 2 Button und probieree diesen Code:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    3. MessageBox.Show("Fokus auf Button2")
    4. Button2.Focus()
    5. End Sub
    6. Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    7. MessageBox.Show("Button2_Click")
    8. End Sub
    9. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hast du das Enter-Event des Buttons Abonniert? Das bezieht sich nicht auf die Enter-Taste deiner Tastatur.

    -> msdn.microsoft.com/de-de/libra…trol.enter(v=vs.110).aspx
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Erst mal Danke für eure Antworten. Ich kann es selbst auch nicht fassen und habe natürlich auch schon in einem Testprojekt versucht, den Fehler nachzustellen. Klappt aber nicht!
    ​Hier mal der Code, wo der Fehler ausgelöst wird:

    VB.NET-Quellcode

    1. Public Sub ShowScanfeld(Modus As Boolean)
    2. If Modus = True Then
    3. frmTeilnehmer.Text = "Scan-Fenster"
    4. frmTeilnehmer.lblÜberschrift.Text = "Bereit zum Scannen ..."
    5. frmTeilnehmer.txtScanEingabe.Location = New Point(14, 60)
    6. frmTeilnehmer.txtScanEingabe.Width = 1046
    7. frmTeilnehmer.txtScanEingabe.Height = 494
    8. frmTeilnehmer.txtScanEingabe.Clear()
    9. frmTeilnehmer.txtScanEingabe.ReadOnly = False
    10. frmTeilnehmer.txtScanEingabe.Focus()
    11. InitFormTeilnehmer()
    12. Else
    13. frmTeilnehmer.Text = "Teilnehmerfenster"
    14. frmTeilnehmer.txtScanEingabe.Location = New Point(800, 63)
    15. frmTeilnehmer.txtScanEingabe.Width = 40
    16. frmTeilnehmer.txtScanEingabe.Height = 30
    17. frmTeilnehmer.txtScanEingabe.Text = "Scan"
    18. frmTeilnehmer.txtScanEingabe.ReadOnly = True
    19. frmTeilnehmer.lblÜberschrift.Text = strVeranstalter
    20. SkipTeilnahme = True
    21. frmTeilnehmer.btnTeilnahmeRückkehr.Select() 'Hier
    22. End If
    23. End Sub


    Zur Erläuterung: Das Textfeld txtScanEingabe ist ein Multiline-Textfeld und wird über diese Prozedur initialisiert. Über den Parameter Modus=True wird es in der Form groß dargestellt und anschließend über einen Scanner ein QR-Code mit mehreren Zeilen eingelesen. Über Text_Change wird der Inhalt zeilenweise ausgelesen und letztlich zugeordneten Textfeldern der Form zugewiesen. Zum Abschluss dieses Vorgangs wird über Modus = False das Textfeld quasi wieder versteckt und zum Schluss der Button btnTeilnahmeRückkehr selektiert, damit er den Focus erhält. Dieser Button soll letztlich die gescannten Daten (nach Prüfung durch den User) in einer DB speichern.
    ​Wenn ich auf die rote Zeile einen Haltepunkt setze und dann einen Einzelschritt ausführe, lande ich im Click-Ereignis des Buttons!! Nach F5 wird der Speichervorgang auch ordnungsgemäß ausgeführt.

    Das Problem ist auch unabhängig von diesem Button. Ganz egal welchen Button ich an dieser Stelle selektiere, es wird immer das Click-Ereignis des selektierten Buttons ausgeführt!

    ​Ich habe jetzt auf die Schnelle das Problem mit dem Flag SkipTeilnahme gelöst, trotzdem wüsste ich gern, wo der Fehler steckt.

    ​Vielen Dank für eure Hilfe
    Jürgen

    ~blaze~: Rot ist den Moderatoren vorbehalten, stattdessen vbnet-Tags mit Kommentar eingefügt

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „~blaze~“ ()

    Public Controls sind dirty. Sollte man nicht machen... Besser wäre es, der Form Properties zu geben oder die Daten im Konstruktor zu übergeben.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @Js1101 Was ist frmTeilnehmer?
    Willst Du die Form fernsteuern?
    Warum machst Du das nicht in der Form selbst?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Guten morgen und Danke für die Antworten.

    ​@ErfinderDesRades .Focus() liefert gleichen Fehler.
    ​@mrMo und @RodFromGermany Das ist doch kein Public Control, sondern ein Public Sub, oder? Ich habe meine eigenen Subs bzw. Functions ein einem eigenen Modul zusammengefasst und in der Form nur die Ereignisprozeduren um die Übersichtlichkeit zu verbessern. In meinen Subs werden natürlich auch Eigenschaften der Controls auf der Form verändert.
    ​Und zu Beginn der Entwicklung hat dieser Part ja fehlerfrei funktioniert. Leider kann ich nicht sagen, ab welchem Weiterentwicklungsstand der Fehler auftrat.
    @Js1101 Aha.
    Ein Modul ist ja so was wie eine Shared-Klasse, sie hat keinen Bezug zur Instanz Deiner Form.
    Gugst Du Dialoge: Instanziierung von Forms und Aufruf von Dialogen
    Wenn Du im Modul mit Form1.DoIt() hantierst, wird von VB.NET eine (weitere) Instanz der Form1 erstellt, und das ist dann nicht die, die Du meinst.
    Pack die betreffenden Prozeduren zurück in die Form, deren Member sie verwendet.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Habe jetzt mal eine komplett abgespeckte Version implementiert, alles in einer Form: Das Ergebnis ist das Gleiche X(

    ​Zum besseren Verständnis: Ich möchte per QRCode-Scanner Daten einscannen, diese in der Form in Textfeldern anzeigen und ggf. korrigieren und dann in eine Datenbank speichern.
    ​Der Scanner schreibt die Daten wie über eine Tastatureingabe in jedes Feld, das Tastatureingaben entgegennehmen kann. Insgesamt enthält der Code 15 Zeilen, die am Ende ein ASCII 13 enthalten.
    ​Zur Realisierung verwende ich ein Multiline-Textfeld, das beim Start der Anwendung über allen Controls angezeigt wird. Wenn alles eingelesen ist, soll dieses Textfeld in seine Zeilen zerlegt werden, die Zeileninhalte in die entsprechende TextBoxen geschrieben werden und anschließend das Multiline-Textfeld unsichtbar gemacht werden, um die Informationen in den anderen Controls zu sehen. Nach dem Speichern wird das Multiline-Textfeld wieder im Vordergrund sichtbar geschaltet, um für den nächsten Scan bereit zu sein.
    ​Ich werte dazu das TextChange-Ereignis aus. Wenn dort nach bestimmten Kriterien (Anzahl eingelesener Zeilen) das Ende des Scanvorgangs erkannt wird, erfolgt die Auswertung des Textfeldes in einer getrennten Prozedur, die am Ende dann den Speichern-Button selektieren, aber nicht auslösen soll. Leider wird dieser dabei jedoch direkt ausgelöst und damit dem User die Möglichkeit zur Korrektur der Daten genommen.

    ​Wenn ich den Scan simuliere, indem ich mir einen String mit den gleichen Informationen zusammenbaue (incl. aller Ascii13-Zeichen) tritt das Problem übrigens nicht auf!

    ​Hat vielleicht jemand noch eine Idee, was da falsch läuft oder auch einen besseren Vorschlag zur Umsetzung des Scanvorgangs?

    ​Auf jeden Fall nochmal Danke für eure Unterstützung...
    @Js1101 OK.
    Du benutzt den Scanner als Tastatur und das richtige Fenster muss den Fokus haben, damit es funktioniert.
    =====
    Probier mal dies, das hab ich schon mit Scannern 2 verschiedener Firmen gemacht:
    Besorge Dir einen Treiber, der den Scanner auf eine RS232 umroutet, den sollte die Scanner-Firma haben, lies dazu die Dokumentation des Scanners.
    Dann öffnest Du das entsprechende SerialPort mit den korrekten Parametern und empfängst im DataReceived-Event des SerialPorts Deinen String.
    Feddich. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Bist du das Programm step by step durch gegangen? Also einen kompletten Ablauf angeschaut? Falls nicht, mach das mal, weil evtl. Kommt dein Fehler von wo ganz anders. Manchmal versteift man sich auf eine Fehlerquelle und stellt dann, viele Stunden später, fest das da z.B. noch nen anderes Event ausgelöst wird. Wieviele und welche Events hat dein Button?
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @mrMo Das geht mit einem als Tastatur arbeitenden Scanner nicht.
    @Js1101 Dass Du einen QRCode-Scanner verwendest, musst Du im 1. Post schreiben, sonst behandeln wir hier nur die Symptome, nicht aber die Ursachen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe das Problem-Programm nun extrem reduziert. Es gibt eine Form, darauf ein Multiline-Textfeld, einen Button
    und folgenden Code:

    Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    txtScanInput.Select()

    End Sub

    Private Sub txtScanInput_TextChanged(sender As Object, e As EventArgs) Handles txtScanInput.TextChanged

    'Jeder QRCode beginnt in der ersten Zeile mit "scan" und enthält 15 Zeilen, die
    'jeweils mit crlf getrennt sind
    'Am Ende der 15. Zeile steht ebenfalls ein crlf

    If txtScanInput.Lines.Length > 0 Then
    If Strings.Left(txtScanInput.Lines(0), 4) = "scan" Then
    If txtScanInput.Lines.Length = 16 Then
    Application.DoEvents()
    txtScanInput.ReadOnly = True
    btnTeilnahmeRückkehr.Select()
    End If
    End If
    End If

    End Sub

    Private Sub btnTeilnahmeRückkehr_Click(sender As Object, e As EventArgs) Handles btnTeilnahmeRückkehr.Click

    MsgBox("Teilnahme geklickt...")
    txtScanInput.Clear()
    txtScanInput.ReadOnly = False
    txtScanInput.Select()

    End Sub

    End Class

    Mit diesem Code funktioniert alles wie gewünscht: Der QRCode wird eingelesen und wenn alle Zeilen eingelesen sind, wird das Textfeld verlassen und der Button selektiert.
    Hier ist allerdings im TextChange das "böse" DoEvents eingefügt. Lasse ich das weg, wird ohne mein Zutun das Click-Event des Buttons ausgelöst.

    Kann das vom crlf am Ende der letzten Zeile herrühren? Oder gibt es eine andere Erklärung?

    P.S. Habe irgendwie Probleme mit der Formatierung des Textes hier. Gibt es irgendwo eine Anleitung zur vernünftigen Erstellung von Themen)

    Js1101 schrieb:

    Gibt es irgendwo eine Anleitung zur vernünftigen Erstellung von Themen



    Binnich echt froh, dass du das fragst, weil so guck ich dein Code eiglich nicht an.
    Hab ich jetzt aber doch, und fund:

    VB.NET-Quellcode

    1. 'Am Ende der 15. Zeile steht ebenfalls ein crlf
    Das wäre eine Erklärung.
    Weil wenn der Focus auf dem Button liegt, und der Scanner generiert ein crlf, dann erreicht dieses crlf den Button, und wird von diesem als [Enter]-Tastendruck verarbeitet:
    Click! machts :D

    Eine einfache Möglichkeit wäre, du verwendest ein MenustripItem statt eines Buttons. Da kann man auch draufklicken, aber son MenustripItem nimmt keinen Focus an.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    RodFromGermany schrieb:

    Besorge Dir einen Treiber, der den Scanner auf eine RS232 umroutet, den sollte die Scanner-Firma haben, lies dazu die Dokumentation des Scanners.

    @Js1101 Diese unwichtige Information hätte ich auch ignoriert. X(
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany: Ich habe die Information nicht ignoriert. Da es sich aber um einen Scanner Baujahr ca. 2004 handelt, der selbst einen RS232-Stecker hat und bei mir über einen Adapter RS232-USB angeschlossen wird, habe ich auf die Schnelle keine Anleitung, geschweige denn Treiber finden können. Mir geht es hier auch in erster Linie um das Verständnis, was hier eigentlich passiert (wer will schon dumm sterben).

    ​@ErfinderDesRades: Danke für den Link. Ich vermute auch, dass es an dem crlf liegt.

    ​Wie Eingangs erwähnt hatte ich ja einen Workaround mittels des Skip_Flags implementiert. Und mit der DoEvents-Anweisung geht es ja noch viel einfacher.
    Damit kann ich leben, auch wenn ich jetzt nicht zu 100% sicher bin, das es am crlf liegt. Vielleicht handelt es sich ja auch um einen Bug in VB2010. Da hab ich noch etwas gefunden hinsichtlich der BackColor-Eigenschaft von Button. Dafür mache ich aber ein neues Thema auf.

    ​Euch Allen Danke für die Hilfe!