Extension Methods: Watermark für Textbox

    • VB.NET

    Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von der_Kurt.

      Extension Methods: Watermark für Textbox

      Mit Hilfe der Extension-Methods wird hier für Textboxen eine Watermark hinterlegt

      VB.NET-Quellcode

      1. ''' <summary>
      2. ''' Erweiterungsmethoden für Watermarks
      3. ''' </summary>
      4. ''' <remarks></remarks>
      5. Module wasserzeichenExtension
      6. ''' <summary>
      7. ''' Auflistung aller verfügbaren Wasserzeichen-Objekte
      8. ''' </summary>
      9. ''' <remarks></remarks>
      10. Private _allregisteredTextboxesWithWatermarks As New List(Of WTM_object)
      11. ''' <summary>
      12. ''' bindet die Wasserzeichen-Methoden an eine Textbox
      13. ''' </summary>
      14. ''' <param name="tb">die Textbox, die das Wasserzeichen erhält</param>
      15. ''' <param name="wasserzeichen">der Text, der als Wasserzeichen angezeigt wird</param>
      16. ''' <remarks></remarks>
      17. <Runtime.CompilerServices.Extension()>
      18. Sub createWatermark(tb As TextBox, wasserzeichen As String)
      19. Dim bereitsvorhanden As Boolean = False
      20. For Each obj_ausderliste In _allregisteredTextboxesWithWatermarks
      21. If obj_ausderliste.usedtextbox Is tb Then
      22. bereitsvorhanden = True
      23. End If
      24. Next
      25. If bereitsvorhanden = False Then
      26. AddHandler tb.GotFocus,
      27. AddressOf wasserzeichen_textbox_GotFocus
      28. AddHandler tb.LostFocus,
      29. AddressOf wasserzeichen_textbox_LostFocus
      30. _allregisteredTextboxesWithWatermarks.Add(
      31. New WTM_object With {.usedtextbox = tb,
      32. .wasserzeichen = wasserzeichen,
      33. .actualfont = tb.Font,
      34. .backcolor = tb.BackColor,
      35. .forecolor = tb.ForeColor,
      36. .textalign = tb.TextAlign,
      37. .usepwchar = tb.UseSystemPasswordChar})
      38. 'Effekt zum ersten Mal anwenden
      39. wasserzeichen_textbox_LostFocus(tb, Nothing)
      40. Else 'if bereitsvorhanden = True
      41. 'Wasserzeichen bereits vorhanden: Ausnahme auslösen
      42. Throw New Exception("Der Textbox '" & tb.Name & "' ist bereits ein wasserzeichen zugeordnet")
      43. End If
      44. End Sub
      45. ''' <summary>
      46. ''' entfernt die Bindung der Textbox zu einem Wasserzeichen
      47. ''' </summary>
      48. ''' <param name="tb">die Textbox, deren Wasserzeichen entfernt wird</param>
      49. ''' <remarks></remarks>
      50. <System.Runtime.CompilerServices.Extension()>
      51. Sub removeWatermark(tb As TextBox)
      52. For Each element_ausderliste In _allregisteredTextboxesWithWatermarks
      53. If element_ausderliste.usedtextbox Is tb Then
      54. 'einmal noch ausführen, um alles auf den Standard zu bringen
      55. wasserzeichen_textbox_GotFocus(tb, Nothing)
      56. RemoveHandler tb.GotFocus,
      57. AddressOf wasserzeichen_textbox_GotFocus
      58. RemoveHandler tb.LostFocus,
      59. AddressOf wasserzeichen_textbox_LostFocus
      60. _allregisteredTextboxesWithWatermarks.Remove(element_ausderliste)
      61. Exit For
      62. End If
      63. Next
      64. End Sub
      65. ''' <summary>
      66. ''' entfernt alle registrierten Wasserzeichen
      67. ''' </summary>
      68. ''' <remarks></remarks>
      69. Sub removeallWatermarks()
      70. For q = _allregisteredTextboxesWithWatermarks.Count - 1 To 0 Step -1
      71. removeWatermark(_allregisteredTextboxesWithWatermarks(q).usedtextbox)
      72. Next
      73. End Sub
      74. ''' <summary>
      75. ''' Eventhandler "GotFocus"
      76. ''' </summary>
      77. ''' <param name="sender"></param>
      78. ''' <param name="e"></param>
      79. ''' <remarks></remarks>
      80. Private Sub wasserzeichen_textbox_GotFocus(sender As Object, e As EventArgs)
      81. Dim tb_sender = CType(sender, TextBox)
      82. For Each aktuelle_standards In _allregisteredTextboxesWithWatermarks
      83. If tb_sender Is aktuelle_standards.usedtextbox Then
      84. If aktuelle_standards.effectisapplied Then
      85. With tb_sender
      86. 'Handler 'kurz' entfernen
      87. 'als Workaround, weil die TB bei Umstellung des Textalign
      88. 'und des PW-Char Probleme macht
      89. RemoveHandler .GotFocus,
      90. AddressOf wasserzeichen_textbox_GotFocus
      91. RemoveHandler .LostFocus,
      92. AddressOf wasserzeichen_textbox_LostFocus
      93. ''Cursor geht in die Box rein,
      94. 'also auf die Standards setzen
      95. .Font = aktuelle_standards.actualfont
      96. .Text = Nothing
      97. .ForeColor = aktuelle_standards.forecolor
      98. .BackColor = aktuelle_standards.backcolor
      99. .TextAlign = aktuelle_standards.textalign
      100. .UseSystemPasswordChar = aktuelle_standards.usepwchar
      101. AddHandler .GotFocus,
      102. AddressOf wasserzeichen_textbox_GotFocus
      103. AddHandler .LostFocus,
      104. AddressOf wasserzeichen_textbox_LostFocus
      105. End With
      106. aktuelle_standards.effectisapplied = False
      107. End If
      108. Exit For
      109. End If
      110. Next
      111. End Sub
      112. ''' <summary>
      113. ''' Eventhandler "LostFocus"
      114. ''' </summary>
      115. ''' <param name="sender"></param>
      116. ''' <param name="e"></param>
      117. ''' <remarks></remarks>
      118. Private Sub wasserzeichen_textbox_LostFocus(sender As Object, e As EventArgs)
      119. Dim tb_sender = CType(sender, TextBox)
      120. For Each element In _allregisteredTextboxesWithWatermarks
      121. If tb_sender Is element.usedtextbox Then
      122. If tb_sender.Text = Nothing Then
      123. With tb_sender
      124. ''Cursor geht raus aus der Textbox,
      125. ''also die Box auf die Watermark-Werte setzen
      126. .Text = element.wasserzeichen
      127. .Font = New Font(.Font,
      128. FontStyle.Italic)
      129. .BackColor = Color.FromKnownColor(KnownColor.Info)
      130. .ForeColor = Color.Gray
      131. .TextAlign = HorizontalAlignment.Left
      132. .UseSystemPasswordChar = False
      133. End With
      134. element.effectisapplied = True
      135. End If
      136. Exit For
      137. End If
      138. Next
      139. End Sub
      140. Friend Class WTM_object
      141. Friend effectisapplied As Boolean
      142. Friend usedtextbox As TextBox
      143. Friend wasserzeichen As String
      144. Friend actualfont As Font
      145. Friend forecolor As Color
      146. Friend backcolor As Color
      147. Friend textalign As HorizontalAlignment
      148. Friend usepwchar As Boolean
      149. End Class
      150. 'TODO: Änderungen der Eigenschaften der Textbox in WTM_objekt integrieren
      151. '##### Änderungen, die an der Textbox gemacht werden, während der Effekt
      152. '##### aktiv ist, müssen noch in die richtigen Bahnen gelenkt werden.
      153. 'TODO: Aussehen des Effekts veränderbar machen
      154. '##### Der Effekt ist im Moment hardcodiert, nur über den Quelltext zu ändern
      155. 'License: "Do whatever you want, but don't blame me"
      156. '######## Der Code darf frei verwendet, verändert werden
      157. '######## Namensnennung nicht notwendig
      158. End Module


      VB.NET-Quellcode

      1. 'erstellen eines Wasserzeichens für eine Textbox:
      2. TextBox1.createWatermark("<LOGIN>")
      3. TextBox2.createWatermark("<PASSWORT>")
      4. 'entfernen eines Wasserzeichens:
      5. TextBox2.removeWatermark()
      6. 'entfernen aller registrierten Wasserzeichen
      7. removeallWatermarks()


      Anwendung: neues Modul :!: erstellen (Modul deshalb, weil Extension-Methods verwendet werden. Diese benötigen ein Modul.)
      Modulcode durch den oberen Code ersetzen. Die Anwendung der Funktionen siehe unteres Beispiel.

      Keine Garantie auf volle Funktionsfähigkeit. Der Code darf frei verwendet und verändert werden. Namensnennung nicht notwendig.

      LG, der_Kurt
      Bilder
      • watermark-textbox.PNG

        15,82 kB, 610×353, 300 mal angesehen

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „der_Kurt“ () aus folgendem Grund: Screenshot hinzugefügt

      Kleine Performance und Schönheitskorrektur in der Sub createwatermark

      VB.NET-Quellcode

      1. For Each obj_ausderliste In _allregisteredTextboxesWithWatermarks
      2. If obj_ausderliste.usedtextbox Is tb Then
      3. bereitsvorhanden = True
      4. Exit For
      5. End If
      6. Next


      Es müssen nicht alle Elemente der Liste durchlaufen werden wenn die Textbox bereits einmal gefunden wurde =)
      Btw. könnte man sicherlicht auch statt einer For Each einfach die Contains-Methode wählen indem man das WTM Object vorher erstellt

      VB.NET-Quellcode

      1. Dim wtm New WTM_object With {.usedtextbox = tb,
      2. .wasserzeichen = wasserzeichen,
      3. .actualfont = tb.Font,
      4. .backcolor = tb.BackColor,
      5. .forecolor = tb.ForeColor,
      6. .textalign = tb.TextAlign,
      7. .usepwchar = tb.UseSystemPasswordChar})
      8. If Not _allregisteredTextboxesWithWatermarks.Contains(wtm) Then
      9. _allregisteredTextboxesWithWatermarks.Add(wtm)
      10. End If


      Edit: und Typenbestimmung ist unter Option Strict On auch wichtig

      VB.NET-Quellcode

      1. For q As Integer = _allregisteredTextboxesWithWatermarks.Count - 1 To 0 Step -1
      2. removeWatermark(_allregisteredTextboxesWithWatermarks(q).usedtextbox)
      3. Next

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

      Hi Dodo!

      Beim ersten Code-Beispiel gebe ich dir Recht. Das "Exit For" habe ich hier wohl vergessen....

      Ich habe mit der Behelfsvariable gearbeitet, weil ich in diesem Beispiel später mal u.A. bei einer Zuweisung eines anderen Wasserzeichen-Textes an eine bereits registrierte Textbox den Wert ändern wollte.
      Dazu wäre es notwendig, zu wissen, ob es diese Objekt schon gibt.
      Das ist ein typischer Fall von: Loch in der Mauer? Stelle einen Schrank davor.
      (Ich habe dieses Projekt abgebrochen, weil der Kunde plötzlich den Errorprovider als Hinweis verwenden wollte.)

      Typenbestimmung ist unter Option Strict On auch wichtig

      VB.NET-Quellcode

      1. For q As Integer = _allregisteredTextboxesWithWatermarks.Count - 1 To 0 Step -1

      Ist richtig, allerdings arbeite ich auch mit Option Infer! Hier wird in meinem Beispiel (ohne "as Integer") q implizit als Integer deklariert (Anfangswert ist Integer, Endwert ist Integer, Step ist Integer). Die Bezeichnung "as Integer" macht es zwar lesbarer, ist hier aber nicht zwingend notwendig.

      Danke für's Durchschauen ;)
      LG, Kurti
      Bilder
      • dim_q.png

        9,08 kB, 403×226, 232 mal angesehen