Eigenes TextBoxControl zeichnen

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von FreakJNS.

    Eigenes TextBoxControl zeichnen

    Hallo.

    Ich würde gerne eine TextBox selbst zeichnen.

    Momentan sieht der Code so aus:


    VB.NET-Quellcode

    1. Public Class OwnTextBox : Inherits TextBox
    2. Private Status As State = State.Normal
    3. Private Texto As String = String.Empty
    4. Private Fonto As Font = New Font("Lucida Grande", 10)
    5. Private Structure TextBoxState
    6. Public ReadOnly left, middle, right As Bitmap
    7. Public Sub New(left As Bitmap, middle As Bitmap, right As Bitmap)
    8. Me.left = left
    9. Me.middle = middle
    10. Me.right = right
    11. End Sub
    12. End Structure
    13. Private textboxStates As TextBoxState() = {New TextBoxState(My.Resources.TextBoxSideUnActivated, My.Resources.TextBoxMiddle, My.Resources.TextBoxSideUnActivated),
    14. New TextBoxState(My.Resources.TextBoxActivatedLinks, My.Resources.TextBoxActivatedMittle, My.Resources.TextBoxActivatedRechts)}
    15. Public Enum State
    16. Normal = 0
    17. Focused = 1
    18. End Enum
    19. Public Sub New()
    20. Me.DoubleBuffered = True
    21. Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    22. Me.SetStyle(ControlStyles.FixedHeight, True)
    23. Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
    24. Me.SetStyle(ControlStyles.ResizeRedraw, True)
    25. Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True)
    26. End Sub
    27. Public Sub Redraw(ausgabe As Graphics)
    28. Dim gr As Graphics = ausgabe
    29. gr.Clear(Me.BackColor)
    30. Dim currtextboxstate As TextBoxState = textboxStates(Status)
    31. gr.DrawImage(currtextboxstate.left, 0, 0, currtextboxstate.left.Width, Me.Height)
    32. For i As Integer = 0 To 5
    33. gr.DrawImage(currtextboxstate.middle, 0, 0, currtextboxstate.middle.Width, Me.Height)
    34. Next
    35. gr.DrawImage(currtextboxstate.right, 0, 0, currtextboxstate.right.Width, Me.Height)
    36. End Sub
    37. <Browsable(True), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
    38. Public Overrides Property Font() As Font
    39. Get
    40. Return Fonto
    41. End Get
    42. Set(Font As Font)
    43. Fonto = Font
    44. Me.Invalidate()
    45. End Set
    46. End Property
    47. <Browsable(True), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
    48. Public Overrides Property Text() As String
    49. Get
    50. Return Texto
    51. End Get
    52. Set(value As String)
    53. Texto = value
    54. Me.Invalidate()
    55. End Set
    56. End Property
    57. Protected Overrides Sub OnLostFocus(e As EventArgs)
    58. MyBase.OnLostFocus(e)
    59. Status = State.Normal
    60. Me.Invalidate()
    61. End Sub
    62. Protected Overrides Sub OnGotFocus(e As EventArgs)
    63. MyBase.OnGotFocus(e)
    64. Status = State.Focused
    65. Me.Invalidate()
    66. End Sub
    67. Protected Overrides Sub OnPaint(pevent As System.Windows.Forms.PaintEventArgs)
    68. Redraw(pevent.Graphics)
    69. End Sub
    70. End Class





    Kann mir jemand sagen was da falsch ist?

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

    du zeichnest zuerst auf ein image und zeichnest dieses dann auf das control. warum?
    zeichne direkt auf das control - also auf das graphics-objekt (pevent.graphics), am besten direkt in der OnPaint-Methode.

    Edit: NullReferenceException heißt immer, dass du groben unfug gemacht hast. Welche Zeile ist der Übeltäter?
    Das ist generell Schwachsinn²³ xD
    Bau das aus, vllt funktioniert es dann. Wenn nicht, dann erstell das Control per Code, wenn da was schiefgeht bekommst du normalerweise die entsprechende Zeile angezeigt. Wichtig: Nicht im Form1-Load-Event arbeiten, das catcht die Fehler einfach weg - also in einen Button packen.

    Edit: Eine Textbox scheint auch ein Contol von der Sorte zu sein, die sich nicht so einfach umbauen lassen - zumindest die Zeichenroutine lässt sich durch das bloße überschreiben der OnPaint-Methode nicht beeindrucken. Google mal nach "Textbox Owner Draw" da findest du ein paar verschiedene wege das zu umgehen. Ob es Sinn macht musst du wissen.

    vbarchiv.net/forum/id10_i12601…nes-controls-aendern.html

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

    Also, dass ich direkt auf das Control zeichne ohne ein Bitmap zu erstellen habe ich jetzt ausprobiert.

    Da darf man aber auf pevent.Graphics kein .Dispose anwenden nach dem Zeichnen stimmts?

    Wie sieht das mit

    VB.NET-Quellcode

    1. pevent.Graphics.Clear(Me.BackColor)
    aus? Ist das überhaupt nötig?
    Hm, also ich hab das jetzt mit dem pevent gemacht ohne temporäres Bitmap aber irgendwie ist
    der Fehler immernoch da.

    Am eigentlichen Zeichnen liegt der Fehler allerdings nicht, denn wenn ich das Paint Event leer lasse kommt der Fehler auch.

    Irgendwas stimmt mit dem Konstruktor nicht.. Muss man da irgendwie was instanzieren oder so? Wobei eine TextBox ja auch nur ein Control ist..

    Edit: Code aktualisiert, fehler besteht aber noch. Siehe erster Post.
    Solche Fehler liegen oft daran, dass du auf Variablen zugreifst, die noch keinen Wert beinhalten. Wenn du zum Beispiel das allererste mal zeichnest, kann es sein, dass die Größe des Controls noch nicht vom Designer gesetzt wurde (blödes Beispiel, aber machts Problem deutlich).

    edit: Zu Testzwecken kannst du auch mal ein paar Try-Catchs reinhauen, die dir MessageBoxen anzeigen. Wenn du die siehst, weißt du wenigstens genau, wo der Fehler begraben liegt.

    Skybird schrieb:

    Das sind ja Ubisoftmethoden hier !

    Bitte VB-Tag benutzen - aber richtig

    füge das ding testweise einfach mal zur Laufzeit zu - nicht per Designer, sondern per ButtonClick.
    Da kriegst du vlt. eine Laufzeit-Fehlermeldung.

    Aber meiner Erfahrung nach ists ausserordentlich problematisch, eine Textbox selbst zu zeichnen. Weil zb die Cursor-Positionierung bleibt ja bei der Textbox, und deine Zeichnung muß dem exakt entsprechen.

    Edit: Stimme FreakJNS zu: post#4 nochmal lesen, insbes. den Edit.

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