Im KeyDown Event CTRL-C, CTRL-X und CTRL-V abfragen

  • VB.NET

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von ThomasG82.

    Im KeyDown Event CTRL-C, CTRL-X und CTRL-V abfragen

    Hi,


    Ich habe eine KeyDown Event Routine.

    VB.NET-Quellcode

    1. Public Sub Bookings_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)


    Ich möchte das Drücken von CTRL-C, CTRL-X, CTRL-V abfangen und dann statt der üblichen Funktionen eigenes Coding ausführen.

    Ich hab schon einiges versucht ... es gibt e.KeyCode, e.KeyData, e.Modifier, e.KeyValue, e.Shift, etc. .... aber nichts scheint mir so richtig zu passen.

    In einem Artikel habe ich etwas von BitMasken (z.B. acCtrlMask) gelesen ... aber diese Masken kann ich nicht finden.Vielleicht feht ein Import?

    Zudem scheint mir, dass die Taste CTRL ein Autorepeat ausführt ... ich will natürlich nur etwas ausführen, wenn zusätzlich eine der Tasten C, X oder V gedrückt wird (case insensitive) - die CTRL Taste allein soll nichts ausführen.

    Irgendwie kriege ich das nicht gebacken. Vielleicht kann mir jemand nachsichtig helfen.

    LG
    Peter

    VB.NET-Quellcode

    1. Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
    2. If e.KeyCode = Keys.V AndAlso e.Control Then MessageBox.Show("Strg+V gedrückt")
    3. End Sub
    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.
    @Peter329 Mit der statischen Property Control.ModifierKeys kannst Du jederzeit und überall im Programm (bitcodiert) die Tasten {Shift, Control und Alt} abfragen:
    learn.microsoft.com/de-de/dotn…eys?view=netframework-4.8
    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!
    Hi,

    vielen Dank erst einmal. ich habe das Coding wie folgt ausprobiert. Vielleicht sollte ich erwähnen, dass ich eine DGV habe und eine bestimmte Zelle editiere. An diese editierte Zelle habe ich meine KeyDown-Event Routine im BeginEdit-Event angeheftet.

    VB.NET-Quellcode

    1. 'Ignore CTRL only (so it will not disturb debugging)
    2. If e.Control AndAlso e.KeyCode = Keys.ControlKey Then Exit Sub
    3. 'Process CTRL-code
    4. If e.Control Then
    5. Select Case e.KeyCode
    6. Case Keys.C
    7. MsgBoxDark.Show("CTRL-C")
    8. Case Keys.X
    9. MsgBoxDark.Show("CTRL-X")
    10. Case Keys.V
    11. MsgBoxDark.Show("CTRL-V")
    12. End Select
    13. e.SuppressKeyPress = True
    14. Exit Sub
    15. End If


    Am besten funktioniert CTRL-X ... die Meldung erscheint und die Daten bleiben erhalten.

    Beim CTRL-V ... erscheint zwar die Meldung ... aber das Clipboard wird trotz "e.SuppressKeyPress = True" eingefügt. Damit könnte ich aber "leben".

    Problematisch ist CTRL-C - hier feuert das KeyDown-Event nicht ... (genauso wenig wie das KeyPress-Event). Es werden aber Daten ins Clipboard eingestellt ... und zwar die ganze Zeile der DGV wenn in der editierten Zelle nichts markiert wurde. Und das ist genau das, was ich vermeiden möchte.

    Kann mir jemand helfen, wie ich CTRL-C abfangen kann ... ich möchte die markierten Daten der editierten Zelle ins Clipboard stellen, bzw. den Nullstring, wenn nichts markiert wurde.

    LG
    Peter

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

    Mir fehlen irgendwie Infos, da ich das mit der fehlenden MessageBox nicht nachstellen kann. Bei mir kommen immer MessageBoxen:

    VB.NET-Quellcode

    1. Friend Class FrmMain
    2. Dim DgvTextBox As TextBox
    3. Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    4. DgvTextBox = DirectCast(e.Control, TextBox)
    5. AddHandler DgvTextBox.KeyDown, AddressOf HandleTextInput
    6. End Sub
    7. Private Sub HandleTextInput(sender As Object, e As KeyEventArgs)
    8. If Not e.Control Then Return
    9. Select Case e.KeyCode
    10. Case Keys.C
    11. MessageBox.Show("CTRL-C")
    12. Case Keys.X
    13. MessageBox.Show("CTRL-X")
    14. Case Keys.V
    15. MessageBox.Show("CTRL-V")
    16. End Select
    17. e.SuppressKeyPress = True
    18. e.Handled = True
    19. End Sub
    20. Private Sub DataGridView1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
    21. If DgvTextBox IsNot Nothing Then RemoveHandler DgvTextBox.KeyDown, AddressOf HandleTextInput
    22. End Sub
    23. End Class
    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.
    @Peter329 Mit FormX.KeyPreview = True kannst Du das in den Form-Key-Handlern abarbeiten.
    Nimm dann keine MessagBox zur Ausgabe, sondern schreibe die empfangenen Codes in ein Label oder so, beim finalen Programm kommt da wohl auch keine MessageBox.
    Da kannst Du wesentlich schneller Deine Möglichkeiten ausprobieren.
    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!
    Was ich noch gesehen hab: MessageBoxen führen zu den CutCopyPaste-Aktionen. Lass sie MessageBoxen weg, dann passiert auch nix mit CutCopyPaste - zumindest nicht bei mir.
    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.
    Erst mal Danke, dass du dich so eingehend mit meinem Problem beschäftigt hast !

    Ich hab das jetzt einmal in einem kleinen Test nachvollzogen. Und da habe ich auch herausgefunden, wo mein Problem mit dem "fehlenden CTRL-C" lag: Ich hatte in der DGV "SelectionMode.FullRowSelect" eingestellt. Wählt man "SelectionMode.CellSelect, dann funktioniert die Sache. Das wäre also geklärt. :)

    Wenn man im EditMode ein Teil der Zelle selektiert und dann CTRL-C drückt ... dann ist alles paletti. Der markierte Text wird wie erwartet ins Clipboard eingestellt. (s. Anhang1)

    ABER: Wenn ich aber KEINEN Text markiere, dann wird irgendwelcher Schrott ins Clipboard gestellt. Selbst wenn ich das Clipboard in diesem Fall selbst lösche (und sicherheitshalber noch vorher 1 Sekunde warte), kommt das nicht zum Tragen. (s. Anhang2)

    Das ist mein Coding:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    3. DataGridView1.Rows.Add("A1", "A2", "A3")
    4. DataGridView1.Rows.Add("B1", "B2", "B3")
    5. DataGridView1.Rows.Add("C1", "C2", "C3")
    6. DataGridView1.Rows.Add("D1", "D2", "D3")
    7. DataGridView1.Rows.Add("E1", "E2", "E3")
    8. DataGridView1.Rows.Add("F1", "F2", "F3")
    9. End Sub
    10. Dim DgvTextBox As TextBox
    11. Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    12. DgvTextBox = DirectCast(e.Control, TextBox)
    13. AddHandler DgvTextBox.KeyDown, AddressOf HandleTextInput
    14. End Sub
    15. Private Sub HandleTextInput(sender As Object, e As KeyEventArgs)
    16. If Not e.Control Then Return
    17. Select Case e.KeyCode
    18. Case Keys.C
    19. Dim myTextbox = DirectCast(sender, TextBox)
    20. Dim strSelected = myTextbox.SelectedText
    21. Threading.Thread.Sleep(1000)
    22. If strSelected = "" Then Clipboard.Clear()
    23. MessageBox.Show("CTRL-C >>>" & strSelected & "<<<")
    24. Case Keys.X
    25. MessageBox.Show("CTRL-X")
    26. Case Keys.V
    27. MessageBox.Show("CTRL-V")
    28. End Select
    29. e.SuppressKeyPress = True
    30. e.Handled = True
    31. End Sub
    32. Private Sub DataGridView1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
    33. If DgvTextBox IsNot Nothing Then RemoveHandler DgvTextBox.KeyDown, AddressOf HandleTextInput
    34. End Sub


    Ich hoffe, jemand kann mir sagen, wie ich das beheben kann.

    LG
    Peter
    Bilder
    • s 2023-02-26 17-44-252.jpg

      37,92 kB, 1.208×491, 50 mal angesehen
    • s 2023-02-26 17-44-539.jpg

      42,69 kB, 1.208×491, 50 mal angesehen
    Riecht so, als ob er den MessageBox-Inhalt kopiert. Ein Fehler in VS?
    Aber wie in Post#8 geschrieben. Lass die MessageBoxen außen vor sein und schreib den Solltext stattdessen in ein Label.
    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:

    Ein Fehler in VS?


    Ich habe jetzt mal die MessageBox weggelassen ... und schon verschwindet auch die merkwürdige Message. Wenn ich meine selbstgeschriebene Klasse MsgBoxDark statt MessageBox verwende, ist übrigens auch alles in Ordnung. Irgendwie klappt da etwas mit dem CTRL-C nicht richtig, wenn man im EditMode keinen Text markiert und dann noch MessageBox.Show() aufruft. Na, wenn man das weiß, dann verkneift man sich das halt mit der MessageBox.

    Jetzt weiß ich alles, was ich benötige, um beim Cut & Paste im Edit Mode meine zusätzlichen Prüfungen auszuführen. Ich bin begeistert.

    Nochmals vielen Dank an die Ratgeber, Daumen hoch und Problem gelöst.

    LG
    Peter
    Nur so nebenbei: der ominöse Inhalt der Zwischenablage ist auch erhältlich, wenn man generell eine MessageBox anzeigen lässt und bei Anzeige derselbigen dann Strg+C drückt:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. MessageBox.Show("Foo", "Bar", MessageBoxButtons.YesNoCancel)
    3. TextBox1.Text = Clipboard.GetText
    4. End Sub


    Vielleicht kein Bug, sondern ein Feature …
    Bilder
    • RawMessageBoxTextInClipboard.png

      3,29 kB, 575×209, 36 mal angesehen
    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.

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

    @VaporiZed ich glaube das ist kein Fehler sondern richtig so. Du kopierst ja den Text aus deinem aktuellen Fenster. Da du nichts markiert hast nimmt er den Text, den er findet. Und damit alles was er an Text im Fenster rendern kann. Selbst wenn es also mehr als nur ne MessageBox wäre würde er allen renderbaren Text nehmen und kopieren. Die Trennlinien sagen ja nur aus, dass es verschiedene Teile im Fenster sind und nicht alles im selben Bereich steht. Quasi ist das sogar schlau, auch wenn es keiner so benötigen wird