User Control Problem

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 25 Antworten in diesem Thema. Der letzte Beitrag () ist von mikeb69.

    User Control Problem

    Hi, ich schon wieder :(
    Für meine Anwendung benötige ich ein simples On Screen Keyboard. Ich weis zwar das ich mit

    VB.NET-Quellcode

    1. Process.start("osk.exe")
    die Windows eigene on Screen Keyboard bekomme, die hat mir aber zu Viele Tasten.
    Also hab ich mir ein UserControl gebastelt:

    Das sind alles Labels, die entsprechend benannt sind und im Text das stehen haben, was drauf steht. (ausser bei Shift, Enter usw. da steht es im Tag)

    Nun hab ich erstmal den Grundcode erstellt und meiner Anwendung hinzugefügt. Leider passiert nix wenn ich auf ein Label im Control klicke...
    Hier mal die Codes:
    User Control:

    VB.NET-Quellcode

    1. Public Class touchKeyboard
    2. Inherits UserControl
    3. Private Sub Label_Click(ByVal sender As Object, ByVal e As EventArgs)
    4. OnKeyPressed(New KeyPressedEventArgs(DirectCast(sender, Label).Text))
    5. End Sub
    6. Public Event KeyPressed As KeyPressedEventHandler
    7. Protected Overridable Sub OnKeyPressed(ByVal e As KeyPressedEventArgs)
    8. RaiseEvent KeyPressed(Me, e)
    9. End Sub
    10. End Class
    11. Public Delegate Sub KeyPressedEventHandler(ByVal sender As Object, ByVal e As KeyPressedEventArgs)
    12. Public Class KeyPressedEventArgs
    13. Inherits EventArgs
    14. Public Sub New(ByVal keyPressed As String)
    15. Me.KeyPressed = keyPressed
    16. End Sub
    17. Private _KeyPressed As String
    18. Public Property KeyPressed() As String
    19. Get
    20. Return _KeyPressed
    21. End Get
    22. Private Set(ByVal value As String)
    23. _KeyPressed = value
    24. End Set
    25. End Property
    26. End Class

    und hier das KeyPressed Ereignis in der Anwendung:

    VB.NET-Quellcode

    1. Private Sub touchKB_KeyPressed(sender As Object, e As oskTouch.KeyPressedEventArgs) Handles touchKB.KeyPressed
    2. Dim tb As TextBox = TryCast(sender, TextBox)
    3. If tb Is Nothing Then Return
    4. tb.Text = e.KeyPressed
    5. End Sub

    kann mir jemand bitte ne Hilfestellung geben?
    Danke Euch
    "Hier könnte Ihre Werbung stehen..."
    Du musst auch die Events der Labels Abbonieren.

    VB.NET-Quellcode

    1. Public Class touchKeyboard
    2. Private Sub touchKeyboard_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    3. For Each lbl As Label In Controls.OfType(Of Label)()
    4. AddHandler lbl.Click, AddressOf OnKeyPressed
    5. Next
    6. End Sub
    7. Public Event KeyPressed As KeyPressedEventHandler
    8. Public Overridable Sub OnKeyPressed(ByVal sender As System.Object, ByVal e As System.EventArgs)
    9. RaiseEvent KeyPressed(Me, New KeyPressedEventArgs(""))
    10. End Sub
    11. End Class

    And i think to myself... what a wonderfuL World!
    Hi @Eddy. ich dachte das hätte ich mit:

    VB.NET-Quellcode

    1. Private Sub Label_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Me.KeyPressed
    2. OnKeyPressed(New KeyPressedEventArgs(DirectCast(sender, Label).Text))
    3. End Sub

    bereits getan
    "Hier könnte Ihre Werbung stehen..."
    OK, hab ich jetzt abgeändert, neu erstellt, aus der Anwendung entfernt, neu hinzugefügt.
    Leider passiert trotzdem nix :(

    EDIT: muss nicht in

    VB.NET-Quellcode

    1. RaiseEvent KeyPressed(Me, New KeyPressedEventArgs(""))
    noch irgendwie der Text des Labels rein?
    "Hier könnte Ihre Werbung stehen..."
    So kannstes uebernehmen.

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. <DefaultEvent("KeyPressed")>
    3. Public Class touchKeyboard
    4. Public Event KeyPressed As KeyPressedEventHandler
    5. Private _KeyPressedEventHandler As New KeyPressedEventHandler(AddressOf OnKeyPressed)
    6. Private Sub touchKeyboard_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    7. For Each lbl As Label In Controls.OfType(Of Label)()
    8. AddHandler lbl.Click, AddressOf LabelsClick
    9. Next
    10. End Sub
    11. Private Sub LabelsClick(ByVal sender As Object, ByVal e As EventArgs)
    12. _KeyPressedEventHandler.Invoke(Me, New KeyPressedEventArgs(DirectCast(sender, Label).Text))
    13. End Sub
    14. Public Overridable Sub OnKeyPressed(ByVal sender As System.Object, ByVal e As KeyPressedEventArgs)
    15. RaiseEvent KeyPressed(Me, e)
    16. End Sub
    17. End Class


    Obwohl so minimal wuerde es schon reichen.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. <DefaultEvent("KeyPressed")>
    3. Public Class touchKeyboard
    4. Public Event KeyPressed(ByVal var As String)
    5. Private Sub touchKeyboard_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    6. For Each lbl As Label In Controls.OfType(Of Label)()
    7. AddHandler lbl.Click, AddressOf LabelsClick
    8. Next
    9. End Sub
    10. Private Sub LabelsClick(ByVal sender As Object, ByVal e As EventArgs)
    11. RaiseEvent KeyPressed(DirectCast(sender, Label).Text)
    12. End Sub
    13. End Class

    And i think to myself... what a wonderfuL World!

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

    Suuuper, Danke @Eddy das funktioniert. (wobei ich njicht sagen kann ob es einen Post vorher nicht auch schon funktioniert hat, denn irgendwei hatte ich immer das gleiche Control hinzugefügt...
    Jetzt kann ich mich noch daran machen, Shift, Enter und Backspace hin zu fummeln :thumbsup:
    "Hier könnte Ihre Werbung stehen..."
    Hi,
    in einem neuen Projekt funktioniert @Eddy´s Variante bestens.
    in meinem Tool leider nicht, und ich glaub, ich weis auch warum.
    Mit: Dim tb As TextBox = TryCast(Me.ActiveControl, TextBox) hole ich mir die Textbox, die gerade den Focus hat.
    Es gibt insgesamt 3 Textboxen in der Anwendung und alle 3 liegen auf einem Panel in einem Splitcontainer.
    Wie komme ich also an die Textboxen dran?

    EDIT: also es scheint am Splitcontainer zu liegen, lege ich das Usercontrol ausserhalb des Splitcontainers und auch die Textboxen, funktioniert es einwandfrei ;(
    wie kann ich das umgehen?
    "Hier könnte Ihre Werbung stehen..."

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

    Me bezieht sich immer auf die Klasse selbst. Wenn ActiveControl keine TextBox ist rapelts.

    mit Dim tb As TextBox = TryCast(Me.ActiveControl, TextBox)

    sonst kommst du so an das Focusierte Control
    SplitContainer1.ActiveControl

    Edit:
    @MichaHo
    Pruefe also verher ob es sich um eine TextBox handelt.
    If ActiveControl.GetType = GetType(TextBox) Then
    And i think to myself... what a wonderfuL World!

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

    @Eddy, @VB1963: Hi ihr zwei.
    Beide Lösungen funktionieren perfekt.
    mein Backspace funktioniert soweit auch (sieht Codetechnisch vielleicht etwas doof aus, wussste aber nicht genau wie ich es direkt im Control umsetzen soll, weil dort ja noch kein Zugriff auf die Textbox besteht)
    Jetzt muss ich nur noch die EnterTaste hinbekommen, das quasi bei Enter in die nächste Textbox gewechselt wird, oder wenns die letzte ist, dann eben zum "Anmelden" Button. Also quasi eigentlich nur der TabStop-Reihenfolge folgen....

    EDIT: grad ne Lösung für Enter gefunden :)

    VB.NET-Quellcode

    1. Private Sub touchKB_KeyPressed(sender As Object, e As oskTouch.KeyPressedEventArgs) Handles touchKB.KeyPressed
    2. Dim tb As TextBox = TryCast(scMainMiddle.ActiveControl, TextBox)
    3. If tb.GetType = GetType(TextBox) Then
    4. If Not tb Is Nothing Then
    5. If e.KeyPressed = "Back" Then
    6. tb.Text = tb.Text.Remove(tb.Text.Length - 1, 1)
    7. ElseIf e.KeyPressed = "Enter" Then
    8. SendKeys.Send("{TAB}")
    9. Else
    10. tb.Text &= e.KeyPressed
    11. tb.SelectionStart = tb.Text.Length
    12. End If
    13. End If
    14. End If
    15. End Sub

    "Hier könnte Ihre Werbung stehen..."

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

    MichaHo schrieb:

    TryCast


    Da du nun versuchst zu casten mit TryCast, brauchst du nur pruefen ob die TextBox Nothing ist. Wenn sie Nothing ist, konnte nicht erfolgreich gecastest werden.

    VB.NET-Quellcode

    1. Dim tb As TextBox = TryCast(ActiveControl, TextBox)
    2. If Not tb Is Nothing Then
    3. '......
    4. End If
    And i think to myself... what a wonderfuL World!
    @Eddy Jou.

    MichaHo schrieb:

    VB.NET-Quellcode

    1. If tb.GetType = GetType(TextBox) Then
    2. If Not tb Is Nothing Then
    dürfte in dieser Reihenfolge knallen, wenn tb Nothing ist.
    Und:
    If tb IsNot Nothing Then
    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!
    @Eddy, @RodFromGermany: Danke Euch, hab ich umgesetzt. Mein erstes, eigenes UserControl ist fertig und funktioniert soweit ganz gut.
    ich poste morgen noch den Code des UserControl, da gibts mit Sicherheit auch noch Verbesserungen...
    "Hier könnte Ihre Werbung stehen..."

    VB.NET-Quellcode

    1. Public Overridable Sub OnKeyPressed(ByVal sender As System.Object, ByVal e As System.EventArgs)
    2. RaiseEvent KeyPressed(Me, New KeyPressedEventArgs(""))
    3. End Sub


    Das kapiere ich leider nicht so ganz, Control.KeyPress erwartet doch einen KeyPressedEventArgs keinen EventArgs. Ungeachtet dessen würde ich mir für jede Taste bzw. Label einen Event Abonieren, dann kannst du auch vernünftige Events Feuern und in deiner GUI entsprechend darauf reagieren.
    Dadurch hast du zwar im UserControl mehr Arbeit, für den Benutzer ist es aber wesentlich konfortabler damit zu arbeiten.
    Hallo @Fakiz: ich benutze den Code aus Post#6 von @Eddy (den gekürzten im Spoiler)

    Bei einer vollwertigen Tastatur gebe ich Dir Recht, da gibt es ja auch mehr Tasten, die es zu behandeln gibt.
    Meine Tastatur ist ja nur für dieses eine Projekt und sehr abgespeckt, es gibt nur die Tasten A-Z und Shift, Backspace und Enter
    Ich behalte das Control aber im Auge und würde es auch gerne weiter entwickeln, allerdings fehlt mir im Moment die Erfahrung daraus ein wirklich gutes Control zu machen.

    EDIT: die Tastatur aus Post#1 habe ich mittlerweile weiter abgespeckt:
    "Hier könnte Ihre Werbung stehen..."
    Hi,
    So, als Nachtrag noch der fertige Code aus dem Control (es ist wirklich nur eine simple Tastatur, siehe Post#16 Bild)

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. <DefaultEvent("KeyPressed")>
    3. Public Class touchKeyboard
    4. Public Event KeyPressed(ByVal var As String)
    5. Public Event BackSpace(ByVal key As String)
    6. Public Event EnterClick(ByVal key As String)
    7. Private Sub touchKeyboard_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
    8. For Each lbl As Label In Controls.OfType(Of Label)()
    9. AddHandler lbl.Click, AddressOf LabelsClick
    10. AddHandler lbl.MouseEnter, AddressOf LabelsMouseEnter
    11. AddHandler lbl.MouseLeave, AddressOf LabelsMouseLeave
    12. Next
    13. End Sub
    14. Private Sub LabelsClick(ByVal sender As Object, ByVal e As EventArgs)
    15. Select Case True
    16. Case sender Is lblBackSpace
    17. RaiseEvent BackSpace("{BKSP}")
    18. Case sender Is lblShift
    19. If lblShift.Tag = "Shift" Then
    20. lblShift.Tag = "Caps"
    21. lblShift.Image = My.Resources.Capslock
    22. For Each lb As Label In Controls.OfType(Of Label)
    23. lb.Text = lb.Text.ToUpper
    24. Next
    25. RaiseEvent KeyPressed(DirectCast(sender, Label).Text.ToUpper)
    26. Else
    27. lblShift.Tag = "Shift"
    28. lblShift.Image = My.Resources.Shift
    29. For Each lb As Label In Controls.OfType(Of Label)
    30. lb.Text = lb.Text.ToLower
    31. Next
    32. RaiseEvent KeyPressed(DirectCast(sender, Label).Text.ToLower)
    33. End If
    34. Case sender Is lblEnter
    35. RaiseEvent EnterClick("{TAB}")
    36. Case Else
    37. RaiseEvent KeyPressed(DirectCast(sender, Label).Text)
    38. End Select
    39. End Sub
    40. Private Sub LabelsMouseEnter(ByVal sender As Object, ByVal e As EventArgs)
    41. DirectCast(sender, Label).BackColor = Color.Gray
    42. End Sub
    43. Private Sub LabelsMouseLeave(ByVal sender As Object, ByVal e As EventArgs)
    44. DirectCast(sender, Label).BackColor = Color.FromArgb(64, 64, 64)
    45. End Sub
    46. End Class

    und der exemplarische Aufruf in einer Form:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub TouchKeyboard1_BackSpace(key As String) Handles TouchKeyboard1.BackSpace
    3. SendKeys.Send(key)
    4. End Sub
    5. Private Sub TouchKeyboard1_EnterClick(key As String) Handles TouchKeyboard1.EnterClick
    6. SendKeys.Send(key)
    7. End Sub
    8. Private Sub TouchKeyboard1_KeyPressed(var As String) Handles TouchKeyboard1.KeyPressed
    9. Dim tb As TextBox = TryCast(SplitContainer1.ActiveControl, TextBox)
    10. If tb IsNot Nothing Then
    11. tb.Text &= var
    12. tb.SelectionStart = tb.Text.Length
    13. End If
    14. End Sub
    15. End Class

    "Hier könnte Ihre Werbung stehen..."
    Hi,
    muss meinen eigenen Thread noch einmal ausgraben.
    In Post #17 steht quasi der komplette Code, daher poste ich Ihn hier nicht mehr hin.
    Ich benötige eine kleine Abänderung.
    Es ist gewünscht, das der 1. Buchstabe immer Groß geschrieben wird, auch nach einem Leerzeichen und die Tastatur dann halt selbstständig umschaltet.
    Also z.Bsp. 1. Buchstabe, Tastatur steht auf groß, Buchstabe wird getippt, Tastatur schaltet auf Klein. User schreibt weiter, Nach Leerzeichen, tastatur schaltet wieder auf groß, Buchstabe wird getippt, tastatur schaltet auf klein.

    Jetzt habe ich absolut keinen Ansatz, WO ich das am besten integriere oder abfange... Hätte da jemand nen Tip für mich?
    Danke Euch
    "Hier könnte Ihre Werbung stehen..."
    @MichaHo,

    naja merk dir halt wann du einen Punkt oder ein Leerzeichen geschrieben hast.
    Am besten in einer gemeinsamen Bool.

    Gleichzeitig färbst du die Shift Taste anders ein.
    Hierfür würde ich in jedem Click Event eine Funktion aufrufen die je nach Flagzustand so oder so färbt.

    Gruss

    mikeb69
    Hallo @mikeb69
    Das mit dem Einfärben mach ich ja bereits.

    VB.NET-Quellcode

    1. Case sender Is lblShift
    2. If lblShift.Tag = "Shift" Then
    3. lblShift.Tag = "Caps"
    4. lblShift.Image = My.Resources.Capslock
    5. For Each lb As Label In Controls.OfType(Of Label)
    6. lb.Text = lb.Text.ToUpper
    7. Next
    8. RaiseEvent KeyPressed(DirectCast(sender, Label).Text.ToUpper)
    9. Else
    10. lblShift.Tag = "Shift"
    11. lblShift.Image = My.Resources.Shift
    12. For Each lb As Label In Controls.OfType(Of Label)
    13. lb.Text = lb.Text.ToLower
    14. Next
    15. RaiseEvent KeyPressed(DirectCast(sender, Label).Text.ToLower)
    16. End If
    17. Case sender Is lblEnter
    18. RaiseEvent EnterClick("{TAB}")
    19. Case Else
    20. RaiseEvent KeyPressed(DirectCast(sender, Label).Text)
    21. End Select


    Das mit den Boolwerten ist ne Gute Idee, ich zerbrech mir nur den Kopp, WO ich das einbauen muss.
    Aus der Tastatur heraus hab ich ja keinen Zugriff auf die Textbox.
    Müsste ich ne Puplic Property machen, die ich dann im Form Code setzen kann oder handel ich das komplett im Usercontrol ab?
    "Hier könnte Ihre Werbung stehen..."