Textbox.Text über KeyDown Event beschreiben

  • VB.NET

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von DerSmurf.

    Textbox.Text über KeyDown Event beschreiben

    Hallo ihr lieben
    Ich habe ein TabControl mit mehreren TabPages.
    Zwei dieser Pages dienen der Darstellung, der Inhalte des angeschlossenen DataSets (Artikel, und Adressen).
    Diese beiden Pages haben neben einem DataGridView noch ein paar Buttons zum bearbeiten der Daten (löschen, editieren und neu erstellen), sowie jeweils eine Textbox zum Filtern der entsprechenden Binding Source.

    Da es auf diesen beiden TabPages eben nur diese eine Textbox gibt, in die eine Tastatureingabe erfolgen kann, möchte ich diese Eingabe über das KeyDown Event realisieren. (oder KeyUp / KeyPress - wenns einfacher ist), damit der User die Textbox nicht immer erst anklicken muss.

    Mein Ansatz ist im Key Down Event der Form die gedrückte Taste abzufragen, dann die aktivierte Tab Page abzufragen und dann ggf. den entsprechenden Wert in die Textbox zu schreiben.
    Aber dann müsste ich ja für alle 3 Bchstaben + 10 Zahlen immer den gleichen Befehl in meinem Code unterbringen.
    Geht das eleganter / kürzer als mein Ansatz?

    VB.NET-Quellcode

    1. Private Sub FrmMainForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
    2. Select Case e.KeyCode
    3. Case Keys.Escape
    4. 'Shortcut für Suche löschen Button (Escape) in Tab Adressbuch
    5. If TCMain.SelectedTab Is TPAddressbook Then DelSearch()
    6. 'Shortcut für Suche löschen Button in Tab Artikel
    7. If TCMain.SelectedTab Is TPArticles Then DelSearchArticles()
    8. Case Keys.Enter
    9. 'Shortcut zum speichern der Rechnungsdaten
    10. If TCMain.SelectedTab Is TPOrders Then SaveOrder()
    11. Case Keys.A
    12. If TCMain.SelectedTab Is TPAddressbook Then TBSearch.AppendText("a")
    13. If TCMain.SelectedTab Is TPArticles Then TBSearchArticles.AppendText("a")
    14. 'usw. für alle Zeichen
    15. End Select
    16. End Sub

    DerSmurf schrieb:

    für alle 3 Bchstaben + 10 Zahlen
    Welche 3 Buchstaben? Oder meinst Du 30? Was ist mit Sonderzeichen? Groß-/Kleinschreibung?
    Das ganze Vorhaben erscheint mit kontraintuitiv für den User. Warum nicht die jeweilige TextBox fokussieren, wenn ne TabPage ausgewählt wird und da ggf. noch die Button-Sonderwünsche (Escape, Enter) abfangen, anstatt global Buchstaben abzufangen und sie irgendwohin zu senden? Dann kannst Du auch TextBox-spezifisch Aktionen ausführen. Dein Vorhaben geht wahrscheinlich eh nur mit KeyPreview, oder?
    Warum ist dieser Thread mit VB6 getaggt?
    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 schrieb:

    Warum ist dieser Thread mit VB6 getaggt?

    Weil ich mich verklcikt habe.

    VaporiZed schrieb:

    Oder meinst Du 30

    Ja, 30. Sorry (26 + ä, ü, ö, ß)

    VaporiZed schrieb:

    Dein Vorhaben geht wahrscheinlich eh nur mit KeyPreview, oder?

    Das kann ich dir nicht mit 100%iger Sicherheit sagen - aber ich bin mir recht sicher, dass dem so ist - also mit KeyPreview.

    Du hast recht, dass das ganze "kontraintuitiv" ist.
    Aber mein Warenwirtschaftssystem, welches ich seid 15 Jahren verwende, bietet genau diese Funktionalität.
    Es ist egal welches Control gerade den Fokus hat.
    Jede Tastatureingabe wird abgefangen (und unten rechts in einer Art Enabled=False Textbox angezeigt.
    Nach diesem Eintrag wird dann die Liste gefiltert.

    Da hab ich mich schon ziemlich dran gewöhnt, und wollte diese Funktionalität nun auch in meinem Programm unterbringen.
    Oder ist dieses aus programmiertechnischer Sicht, grauenvoll - bzw. so grauenvoll, dass ich es lieber lassen sollte?
    Denn wenn ich, geschätzt, am Ende meines Projektes 12 TabPages habe, von denen nur zwei diese "Filter Textboxen" besitzen, fange ich ja auf den restlichen 10 die Tastenanschläge vollkommen sinnloserweise ab.
    immer den gleichen Befehl in meinem Code unterbringen.Geht das eleganter / kürzer als mein Ansatz?

    Suchst du so etwas, wo du im einzelnen Case-Zweig verschiedene Fälle angeben kannst:

    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' In der Form
    3. ''' Me.KeyPreview = True
    4. ''' einstellen
    5. ''' </summary>
    6. Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
    7. Select Case e.KeyCode
    8. Case Keys.D0 To Keys.D9 '0-9
    9. Debug.WriteLine(Convert.ToChar(e.KeyCode))
    10. Case Keys.NumPad0 To Keys.NumPad9 'Zehnertastatur 0-9
    11. Debug.WriteLine(Convert.ToChar(e.KeyCode - 48))
    12. Case Keys.A To Keys.Z, Keys.Escape, Keys.Enter
    13. Debug.WriteLine(e.KeyCode.ToString)
    14. End Select
    15. End Sub

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VB1963“ ()

    Jo. Das ist doch cool.
    Das macht zumindest aus etlichen Zeilen, nur ein paar Zeilen Code.

    Dann bleibt nur die Grundsatzfrage.
    Gehört der Code ins KeyDown Event der Form, oder gehört der Code eher ins KeyDown Event der einzelnen TabPages, die die Tastenanschläge dann auch tatsächlich verwertden?

    DerSmurf schrieb:

    Gehört der Code ins KeyDown Event der Form, oder gehört der Code eher ins KeyDown Event der einzelnen TabPages, die die Tastenanschläge dann auch tatsächlich verwerten?
    Da hast du dir die Antwort schon selber gegeben. Je eingegrenzter die Tastenanschläge liegen, desto besser ist es - würde ich sagen...
    Hmm. Da bin ich zu doof zu.
    Ich habe eine Form mit TabControl1. Außerdem habe ich KeyPreview dieser Form auf True (per Designer)
    Das TabControl hat die beiden TabPages, TabPage1 und TabPage2.

    Ich habe nun manuell (weil ich es im Designer beim "Blitz" nicht auswählen kann), das TabPage1 KeyDown Event hinzugefügt.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
    3. Select Case e.KeyCode
    4. Case Keys.S
    5. MessageBox.Show("S auf Form Key Down")
    6. End Select
    7. End Sub
    8. Private Sub TabPage1_KeyDown(sender As Object, e As KeyEventArgs) Handles TabControl1.KeyDown 'TabPage1
    9. Select Case e.KeyCode
    10. Case Keys.A
    11. MessageBox.Show("A auf TabPage1")
    12. End Select
    13. End Sub
    14. End Class

    Jedoch kann ich bei "Handles" nur TabControl1 angeben, jedoch möchte ich ja eigentlich TabPage1 haben, damit das KeyDown nicht fürs gesamte TabControl gilt, sondern nur für diese eine TabPage.
    Schreibe ich Handles TabPage1.KeyDown, passiert nach Tastendruck "a" einfach nix.
    Jegliche genauere referenzierung der TabPage1 (Me.TabControl1.TabPage1), oder Me.TabPage1, werde mit einem Fehler quitiert.

    Was muss ich also machen, um ein Key Down Event für eine einzelne TabPage zu abonnieren?

    Edit: Hab mal ein DemoProjekt angehängt, dann braucht ihr das nicht tun, falls die Lösung (für euch) nicht tivial ist.
    Dateien
    • TPKeyDown.zip

      (17,89 kB, 89 mal heruntergeladen, zuletzt: )

    VB.NET-Quellcode

    1. Private Sub TabPage1_KeyDown(sender As Object, e As KeyEventArgs) Handles TabControl1.KeyDown
    2. Dim _sender As TabControl = DirectCast(sender, TabControl)
    3. Select Case e.KeyCode
    4. Case Keys.A
    5. If _sender.SelectedTab Is TabPage1 Then
    6. Console.WriteLine($"{e.KeyCode.ToString} auf {_sender.SelectedTab.Name}")
    7. End If
    8. End Select
    9. End Sub

    Das dürfte selbsterklärend sein.

    @DerSmurf habe nochmal editiert.

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

    Ja, das ist selbsterklärend.
    Aber dann kann ich ja auch das KeyDown der Form verwenden.
    Es geht ja eben darum, das KeyDown der TabPage abzufangen, um das hier zu erfüllen:

    VB1963 schrieb:

    Je eingegrenzter die Tastenanschläge liegen, desto besser ist es - würde ich sagen...


    Edit hieru: Die Hauptform meines Programms hat ein Menüstrip und eben das Tabcontrol.
    Alle anderen Elemente liegen "unterhalb" des Tabcontrols.
    Also macht es ja keinen Unterschied, ob ich das KeyDown der Form, oder das KeyDown des Tabcontrols verwende.
    Oder hab ich da jetzt einen Denkfehler?

    Und um die Abfrage nach aktivem TabControl zu vermeiden und um die "Tastenanschläge möglichst weit einzugrenzen", suche ich eben eine Möglichkeit ein eventuelles KeyDown Ereignis der einzelnen TabPages zu verwenden.


    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DerSmurf“ ()

    Mehr gekapselt geht scheinbar nicht.
    KeyDown, als auch KeyPress des TabPage controls reagieren einfach gar nicht.
    Hah, dann bin ich ja doch nicht zu doof :o)

    Aber dann kann ih doch auch einfach das KeyDown der Form verwenden.
    Weil das (bei meinen Gegebenheiten) keinen Unterschied macht.
    Oder ist hier etwas falsch dran?

    @FormFollowsFunction
    Habe dein Edit gesehen.
    Aber der neue Code ändert ja das Problem, bzw. meine Frage, nicht.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DerSmurf“ ()

    Kannste natürlich machen, das wäre dann aber das Gegenteil von ...

    VB1963 schrieb:

    Je eingegrenzter die Tastenanschläge liegen, desto besser ist es - würde ich sagen...


    Ich denke, das TabControl Event ist schon der richtige Ort.
    Hmm. Ok

    Dann konkretisiere ich meine Frage mal:
    Vorhanden ist eine Form mit MenüStrip und TabControl.
    Alle anderen Controls befinden sich innerhalb des TabControls.

    Spielt es nun eine Rolle, ob ich die Tastenanschläge im KeyDown der Form, oder im KeyDown des TabControls abfange?
    Für mich gehört das ganze ins KeyDown der Form, denn ich denke, das TabControl hat keinen Fokus, wenn ich im MenüStrip auf ein Item klicke?
    Ich mach es mal in Stichpunkten - dann ist weniger Text.
    Hauptform besitzt MenüStrip und TabControl. Keine weiteren Controls außerhalb des TabControls.
    Im TabControl (ca. 12 TabPages), gibt es zwei TabPages mit einer Textbox.
    Diese TB filtert das jeweils darunterliegende DataGridView.
    Damit ich die TB nicht immer erst anklicken muss (bin es ohne anklicken gewöhnt), möchte ich auf diesen beiden TabPages jeden Tastaturanschlag eines verwertbaren Zeichens (Buchstaben und Zahlen) direkt an die Textbox übergeben.
    Nach diesem Schema: bzw. auf diese Art, aber mit dem Code, den @VB1963 oben gepostet hat.

    VB.NET-Quellcode

    1. Private Sub FrmMainForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
    2. Select Case e.KeyCode
    3. Case Keys.Escape
    4. 'Shortcut für Suche löschen Button (Escape) in Tab Adressbuch
    5. If TCMain.SelectedTab Is TPAddressbook Then DelSearch()
    6. 'Shortcut für Suche löschen Button in Tab Artikel
    7. If TCMain.SelectedTab Is TPArticles Then DelSearchArticles()
    8. Case Keys.A
    9. If TCMain.SelectedTab Is TPAddressbook Then TBSearch.AppendText("a")
    10. If TCMain.SelectedTab Is TPArticles Then TBSearchArticles.AppendText("a")
    11. End Select
    12. End Sub

    Die konkrete Frage ist nun, nehme ich deinen (@FormFollowsFunction) Code im KeyDown des TabControls, oder meinen im KeyDown der Form?
    In ein TabControl kann man keinen Code nehmen.
    Man könnte für die Tabs je ein UserControl entwickeln - da kann man Code reinnehmen.
    Bei 12 Tabs könnte das sinnvoll sein, weil sonst kann der Form-Code irrsinnig unübersichtlich werden.
    Aber wäre ein umfangreicher Umbau der Anwendung.

    Wiedemauchsei
    Jo - ich finde auch nur fürs Form die KeyPreview - also wird das wohl Form-Code bleiben müssen.
    Innerhalb des KeyPreview-Events muss man dann halt abfragen, wo der Focus ist.
    Hat man UserControls ist die Abfrage recht einfach.
    Nee - wenn eh nur 1 TabControl existiert, ists sogar noch einfacher, einfach den Tabindex abzufragen.
    So. Sieht glaube ich ganz gut aus:

    VB.NET-Quellcode

    1. Private Sub FrmMainForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
    2. Select Case e.KeyCode
    3. Case Keys.Escape 'Löschen von Suchen Textboxen
    4. If TCMain.SelectedTab Is TPAddressbook Then DelSearch()
    5. If TCMain.SelectedTab Is TPArticles Then DelSearchArticles()
    6. If TCMain.SelectedTab Is TPCustomerOrders Then DelCustomerOrderSearch()
    7. Case Keys.Enter 'Shortcut zum speichern der Rechnungsdaten
    8. If TCMain.SelectedTab Is TPOrders Then SaveOrder()
    9. 'Tasten für Suchen textboxen
    10. Case Keys.D0 To Keys.D9 '0-9
    11. If TCMain.SelectedTab Is TPAddressbook Then TBSearch.AppendText((Convert.ToChar(e.KeyCode)))
    12. If TCMain.SelectedTab Is TPArticles Then TBSearchArticles.AppendText((Convert.ToChar(e.KeyCode)))
    13. If TCMain.SelectedTab Is TPCustomerOrders Then TBSearchCorder.AppendText((Convert.ToChar(e.KeyCode)))
    14. Case Keys.NumPad0 To Keys.NumPad9 'Zehnertastatur 0-9
    15. If TCMain.SelectedTab Is TPAddressbook Then TBSearch.AppendText((Convert.ToChar(e.KeyCode - 48)))
    16. If TCMain.SelectedTab Is TPArticles Then TBSearchArticles.AppendText((Convert.ToChar(e.KeyCode - 48)))
    17. If TCMain.SelectedTab Is TPCustomerOrders Then TBSearchCorder.AppendText((Convert.ToChar(e.KeyCode - 48)))
    18. Case Keys.A To Keys.Z 'Buchstaben
    19. If TCMain.SelectedTab Is TPAddressbook Then TBSearch.AppendText((Convert.ToChar(e.KeyCode.ToString.ToLower)))
    20. If TCMain.SelectedTab Is TPArticles Then TBSearchArticles.AppendText((Convert.ToChar(e.KeyCode.ToString.ToLower)))
    21. If TCMain.SelectedTab Is TPCustomerOrders Then TBSearchCorder.AppendText((Convert.ToChar(e.KeyCode.ToString.ToLower)))
    22. Case Keys.Back 'Backspace
    23. If TCMain.SelectedTab Is TPAddressbook Then
    24. If TBSearch.Text <> "" Then TBSearch.Text = TBSearch.Text.Remove(TBSearch.Text.Length - 1, 1)
    25. End If
    26. If TCMain.SelectedTab Is TPArticles Then
    27. If TBSearchArticles.Text <> "" Then TBSearchArticles.Text.Remove(TBSearchArticles.Text.Length - 1, 1)
    28. End If
    29. If TCMain.SelectedTab Is TPCustomerOrders Then
    30. If TBSearchCorder.Text <> "" Then TBSearchCorder.Text.Remove(TBSearchCorder.Text.Length - 1, 1)
    31. End If
    32. End Select
    33. End Sub


    Ich finde aber bei Google nichts, wie ich Sonderzeichen (ä, ü, ö und ß) mittels Key. abfragen kann.