SendKeys.Send

  • VB.NET

Es gibt 22 Antworten in diesem Thema. Der letzte Beitrag () ist von JLH.

    SendKeys.Send

    Hallo,

    ich lese Daten in TextBoxen mit myStream.Readline ein. Nach dem Einlesen möchte ich, daß mit SendKeys.Send("{TAB}") die TextBoxen "durchgetabbed" werden. Dadurch werden die entsprechenden Berechnungen angestoßen. Ich habe mir etwas wie

    VB.NET-Quellcode

    1. Do Until txtZähne.Focused = True
    2. SendKeys.Send("{tab}")
    3. Loop


    vorgestellt aber es funktioniert nicht. Es sollte alle Texboxen durchtabben bis es wieder an der ersten, txtZähne, ankommt. Jemand eine Idee?
    Laut offizieller Doku schreibt man die Worte groß, also in deinem Fall {TAB}. Das schon versucht? Kann natürlich sein, dass das nicht case-sensitive ist.

    Das Formular hat aber den Fokus, oder?

    Das = True kannst du übrigens wegkürzen.

    EDIT: Moment, fängst du etwa bei txtZähne an? Dann wird er natürlich nicht weiter machen, weil die Bedingung schon erfüllt ist. Dann muss die Schleife fußgesteuert sein:

    VB.NET-Quellcode

    1. Do
    2. SendKeys.Send("{TAB}")
    3. Loop Until txtZähne.Focused

    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    JLH schrieb:

    Dadurch werden die entsprechenden Berechnungen angestoßen.
    Mach Dir UserControls mit einem geeigneten Interface, sammle diese Interface ein und rufe die entsprechenden Funktionen über Interface auf.
    Ohne SendKeys.
    Gugst Du hier: Finden aller Controls mit gemeinsamer Basisklasse in einer Form mit TabControls
    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!
    Das beschriebene Wunschvorgehen ist Pfeil-Rücken-Brust-Auge. Warum werden die Daten nicht eingelesen, verteilt und dann die Berechnungen gestartet:

    Quellcode

    1. ---Pseudocode---
    2. Daten = LeseDatenEin()
    3. VerteileDatenAnControls(Daten)
    4. BerechneWasAuchImmer()

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Marcus Ich hab die im Code groß, ist aber tatsächlich nicht case senitive. Zum schauen ob sich überhaupt etwas tut habe ich vor dem Loop 2 SendKeys.Send("{TAB}") was auch ausgeführt wird, das Loop aber nicht.

    Das Programm ist wie eine Tabellenkalkulation aufgebaut. Wird eine Zelle (TextBox) verlassen wird gerechnet. Dazu verwende ich entweder "txtXXX.leave" oder "txtYYY.validated"

    @Rod, Deine Lösung kappier ich nicht, dazu ist mein Wissen zu gering. Könnte ich damit ein "leave" oder "validated" simulieren?
    @VaporiZed die Daten werden korrekt verteilt. Was ich brauche ist ein Weg die Berechnungen zu starten. Ganz einfach und funktioniert auch ist die TAB-Taste zu halten bis er durch ist. Aber das geht ja garnicht
    Lagere doch deinen Code aus den einzelnen Leave-Routinen jeweils in einen eigene Prozedur aus.
    Beim Import arbeitest Du dann einfach die einzelnen Routinen ab und kein SendKey ist notwendig.
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).
    Ist viel zu aufwendig... das muß doch einfacher gehen.

    Hab gerade

    VB.NET-Quellcode

    1. txtZähne.Focus()
    2. txtModul.Focus()
    3. txtEWinkel.Focus()
    4. txtUni1.Focus()
    5. txtUni2.Focus()


    probiert. Geht auch. Kann man sowas mit einer Schleife machen wie in Rod's Sammeln aller Labels? Allerdings sollte es in der Reihenfolge der TabIndexe gehen.

    JLH schrieb:

    Könnte ich damit ein "leave" oder "validated" simulieren?
    Was meinst Du damit?
    Mit Aktivieren über .Focus() handelst Du Dir bei nächster Gelegenheit weitere Probleme ein, insbesondere, wenn die Reihenfolge stimmen muss.
    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!
    Nun ja… wenn ein User das Formular ausfüllt bewegt er sich von Eingabe zu Eingabe und bestätigt dies entweder mit Enter oder Tab oder er klickt mit der Maus in das nächste auszufüllende Feld. Da ich kein Freund von Buttons für Berechnen bin triggert das verlassen einer Zelle eine Berechnung an der der Wert dieser Zelle beteiligt ist. Zuvor gespeicherte Berechnungen werden nur die Eingaben gespeichert und sequenziell an die entsprechende Zelle gegeben. Die Daten müssen jetzt berechnet werden als hätte man dies per Hand eingetragen. Da jetzt zwar alle Zellen gefüllt sind aber kein Event passiert wird auch nichts berechnet. Klar kann man jetzt einfach Return oder Tab drücken bis man einmal durch ist aber das ist nicht im Sinne des Erfinders. Kann man sowas nicht simulieren? Eigentlich mit sendkeys?

    Mit .Focus habe ich zwischenzeitlich tatsächlich schlechte Erfahrungen gemacht…
    @JLH Ich halte Deine Herangehensweise für sehr fehleranfällig.
    Was passiert, wenn der Operator die Reihenfolge der Eingabe nicht befolgt?
    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!
    Der Anwender kann ausfüllen wie er will sofern die Module freigeschaltet sind. Die Vorgabe mit dem TabIndex dient genau dazu die Bereiche erst zu aktivieren. Vielleicht erinnerst du dich als ich ausgeblendete Textboxen aktivieren und dann anspringen wollte?

    VB.NET-Quellcode

    1. Private txtZähne_LostFocus(sender As Object, e As EventArgs) Handles txtZähne.LostFocus
    2. BerechneDatenFürtxtZähne()
    3. End Sub
    4. Private txtModul_LostFocus(sender As Object, e As EventArgs) Handles txtModul.LostFocus
    5. BerechneDatenFürtxtModul()
    6. End Sub

    usw.

    Das Auslagern von Code in Methoden erlaubt Dir dessen Wiederverwendung an anderer Stelle, z.B. beim Datenimport, siehe Post#4. Was spricht dagegen?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    OK... hier mal ein paar Zeilen wie ich das umsetze. Vielleicht mache ich das ja nicht ganz den Regeln konform:

    VB.NET-Quellcode

    1. Private Sub txtZähne_Validating(sender As Object, e As CancelEventArgs) Handles txtZähne.Validating
    2. Z = Val(txtZähne.Text)
    3. If Z < 5 Or Z > 200 Then
    4. e.Cancel = True
    5. txtZähne.Select(0, txtZähne.Text.Length)
    6. ErrorProvider.SetError(txtZähne, "Mindestens 6 und maximal 200 Zähne")
    7. End If
    8. End Sub
    9. Private Sub txtModul_Validating(sender As Object, e As CancelEventArgs) Handles txtModul.Validating
    10. M = Val(txtModul.Text)
    11. If M = 0 Then
    12. e.Cancel = True
    13. txtModul.Select(0, txtModul.Text.Length)
    14. ErrorProvider.SetError(txtModul, "Zahl > 0")
    15. End If
    16. End Sub
    17. Private Sub txtEWinkel_Validating(sender As Object, e As CancelEventArgs) Handles txtEWinkel.Validating
    18. EW = Val(txtEWinkel.Text)
    19. If EW = 0 Or EW > 90 Then
    20. e.Cancel = True
    21. txtEWinkel.Select(0, txtEWinkel.Text.Length)
    22. ErrorProvider.SetError(txtEWinkel, ">0 und <90")
    23. End If
    24. End Sub
    25. Private Sub txtZähne_Validated(sender As Object, e As EventArgs) Handles txtZähne.Validated
    26. ErrorProvider.SetError(txtZähne, "")
    27. Berechnen_RG()
    28. lblD0.Text = String.Format("{0:0.000000}", Math.Round(D0, 6))
    29. lblRg.Text = String.Format("{0:0.000000}", Math.Round(RG, 6))
    30. End Sub
    31. Private Sub txtModul_Validated(sender As Object, e As EventArgs) Handles txtModul.Validated
    32. ErrorProvider.SetError(txtModul, "")
    33. Berechnen_RG()
    34. lblD0.Text = String.Format("{0:0.000000}", Math.Round(D0, 6))
    35. lblRg.Text = String.Format("{0:0.000000}", Math.Round(RG, 6))
    36. End Sub
    37. Private Sub txtEWinkel_Validated(sender As Object, e As EventArgs) Handles txtEWinkel.Validated
    38. ErrorProvider.SetError(txtEWinkel, "")
    39. Berechnen_RG()
    40. lblD0.Text = String.Format("{0:0.000000}", Math.Round(D0, 6))
    41. lblRg.Text = String.Format("{0:0.000000}", Math.Round(RG, 6))
    42. End Sub


    Jetzt müßte ich das alles in Methoden packen damit ich es in anderen Bereichen wieder verwenden kann? Wir reden über 5000 Zeilen Code. Das hier sind die absolut einfachsten Zeilen der Berechnungen.... Ich habe mal ein Video angehängt. Schaut Euch mal bitte an wie das ganze funktioniert bzw funktionieren sollte. Ich mache das "Tabben" manuell. Vielleicht wird es klarer :)

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

    JLH schrieb:

    Visual Basic-Quellcode

    1. M = Val(txtModul.Text)
    Mit welcher Programmiersprache arbeitest Du?
    Unter .NET gibt es NumericUpDown-Controls, die da möglicherweise angebracht sind.
    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!
    Und was würde passieren, wenn beim Datenimport bei einer Stelle ungültige Daten drin sind? Das Programm würde sich wahrscheinlich scheinbar aufhängen, weil es versucht, weitere Daten zu verteilen, aber das Validating-Ereignis beim betroffenen Control ein Verlassen verhindert.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed Jou.
    JLH betrachtet sein Problem von innen und schaut nach außen. Unter diesem Blickwinkel kommen Fehlerquellen bei der Dateneingabe leider nicht vor.
    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!
    Wo sollen die ungültigen Daten denn herkommen? Schaut doch bitte das Video an… dann wird bestimmt einiges klarer.

    Und selbst wenn Fehler drin wären ist doch mein Wunsch die Sache durchzutabben genau richtig… weil genau so die eingelesenen Werte nochmal (unnötigerweise) geprüft werden.
    Bei einlesen der Daten passiert ja noch garnichts außer daß die Variablen gefüllt werden. Da ja dabei, und das ist ja mein Problem, kein einziger meiner verwendeten Events zum anstoßen der Berechnung ausgelöst wird, wird auch nichts gemacht. Es findet ja schlicht und ergreifend nichts statt! Erst durch das drücken der Return oder tab Taste setzt sich das ganze wieder in Bewegung.

    Da die gelesenen Zahlen bei der ursprünglichen Berechnung ja bereits geprüft wurden sind diese natürlich korrekt. Es sei denn einer von Euch schreibt mir in die Datei irgendwelche zahlen rein um mich zu ärgern.

    So lese ich die Daten wieder ein die irgendwann zuvor mit Writeline geschrieben wurden:

    VB.NET-Quellcode

    1. txtZähne.Text = myStream.ReadLine
    2. txtModul.Text = myStream.ReadLine
    3. txtEWinkel.Text = myStream.ReadLine
    4. lstParameter.SelectedIndex = myStream.ReadLine
    5. txtUni1.Text = myStream.ReadLine
    6. txtUni2.Text = myStream.ReadLine
    7. lblUni.Name = myStream.ReadLine

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „JLH“ ()

    Ich werf einfach mal alle Bedenken über Bord und komme zurück zu Post#1.
    Du musst Deinen SendKeys-Schleifencode mit dem bei mir beliebtem Delay-Workaround etwas modifizieren, weil sonst das GUI nicht hinterherkommt bzw. nicht die passenden Events gefeurt werden.

    VB.NET-Quellcode

    1. Private Async Sub DeinImportmethode() 'Async
    2. '…
    3. Do Until txtZähne.Focused
    4. SendKeys.Send("{tab}")
    5. Await Threading.Tasks.Task.Delay(1) 'Delay
    6. Loop
    7. '…

    Ohne den klappt es bei mir nicht. Da wird sogar dann Visual Studio beim Debuggen durchgetabbt 8|
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    JLH schrieb:

    Wo sollen die ungültigen Daten denn herkommen?
    Das wirst Du Dich genau dann fragen, wenn sie da sind.
    Ein Teil meiner Arbeit besteht darin, genau so was zu verhindern. Da werden z.B. vorsätzlich ungültige Daten generiert, um zu sehen, was da passiert.
    Das haben wir gerade in China gesehen, denn die Chinesen lesen keine Handbücher, die können eben einfach alles so.
    Oder eben auch nicht...
    Und dann ist stets die Software fehlerhaft. ;)
    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!