Me.Invalidate bei Usercontrol macht Probleme

  • VB.NET

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

    Me.Invalidate bei Usercontrol macht Probleme

    Hallo Liebe Community, mal wieder stehe ich vor einem Rätsel.

    Das Rätsel hat einen für mich nicht definierbaren Ursprung.

    Folgendes Problem :

    Ich habe ein Usercontrol erstellt, welches ich komplett mit GDI zeichnen lasse. Das mache ich mit der "Control_Paint" methode. Das Zeichnen veranlasse ich durch "Control.Invalidate" welches alle 25ms in einem Thread ausgeführt wird.

    Wenn ich das Usercontrol jetzt auf meiner Form platziere, und der Thread startet, dann sind alle Pictureboxen die sich auf der Form befinden welches das Control enthält schwarz. und es tut sich nichts mehr. Nur das Control arbeitet ordnungsgemäß.

    Ich verstehe das nicht. Was kann ich machen das ich trotzdem die Bilder der Picturebox weiterhin sehe ?


    Grüße
    Slayers

    Slayers schrieb:

    welches alle 25ms in einem Thread ausgeführt wird.

    Wozu soll das gut sein.
    Invalidisiere Dein Control genau dann, wenn sich der Inhalt ändert.
    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!
    Das tut es ja. Ich möchte gerne einen Text á la Ticker anzeigen lassen. Du weißt ja in diesem Falle worum es geht.

    Vielleicht gibt es auch eine andere Möglichkeit einen Newsticker darzustellen. Vielleicht könne mir da jemand mal zur Seite stehen. Ich bin echt am verzweifeln. und die Deadline ist der 4.10

    Slayers schrieb:

    Vielleicht gibt es auch eine andere Möglichkeit einen Newsticker darzustellen.

    Was verstehst Du darunter?
    Soss es im Takt flackern?
    Dann nimm lieber den Timer und schalte das Control

    VB.NET-Quellcode

    1. Visible = False
    2. Sleep(nn)
    3. Visible = True
    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!
    Der Timertakt ist also der Text-Fließ-Takt?
    Rufst Du das Invalidate von außen auf?
    Übergib lieber den Text und lass das Control den Rest allein machen.
    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!
    Zur zeit mache ich es so :

    Quellcode

    VB.NET-Quellcode

    1. Option Explicit On
    2. 'Option Strict On
    3. Namespace NewsTickerS
    4. Public Class NewsTicker
    5. Inherits System.Windows.Forms.UserControl
    6. #Region " Vom Windows Form Designer generierter Code "
    7. ' Für Windows Form-Designer erforderlich
    8. Private components As System.ComponentModel.IContainer
    9. 'HINWEIS: Die folgende Prozedur ist für den Windows Form-Designer erforderlich
    10. 'Sie kann mit dem Windows Form-Designer modifiziert werden.
    11. 'Verwenden Sie nicht den Code-Editor zur Bearbeitung.
    12. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
    13. Me.SuspendLayout()
    14. '
    15. 'NewsTicker
    16. '
    17. Me.BackColor = System.Drawing.SystemColors.Control
    18. Me.DoubleBuffered = True
    19. Me.Name = "NewsTicker"
    20. Me.Size = New System.Drawing.Size(301, 23)
    21. Me.ResumeLayout(False)
    22. End Sub
    23. #End Region
    24. #Region " --------------->> Enumerationen der Klasse "
    25. '{Enumerationen}
    26. #End Region '{Enumerationen der Klasse}
    27. #Region " --------------->> Eigenschaften der Klasse "
    28. '{Eigenschaften}
    29. Private Painter As Graphics = Graphics.FromHwnd(Me.Handle)
    30. Private BMP As Bitmap
    31. Private CurrentX As System.Single = Me.Height
    32. Private WaitIntervall As Integer = 25
    33. Private FadeIntervall As Integer = 75
    34. Private Fade As Boolean = False
    35. Private Delegate Sub DInvalidate()
    36. Private MausLocation As Single
    37. Private _NewsCustom As New System.Collections.Generic.List(Of NewsTickerS.NewsString)
    38. #End Region '{Eigenschaften der Klasse}
    39. #Region " --------------->> Konstruktor und Destruktor der Klasse "
    40. '{Konstruktor/ Destruktor}
    41. Public Sub New()
    42. '{Konstruktor}
    43. MyBase.New()
    44. InitializeComponent()
    45. 'BMP = New Bitmap(Me.Width, Me.Height)
    46. 'Painter = Graphics.FromHdc(Me.Handle) ' System.Drawing.Graphics.FromImage(BMP)
    47. 'Me.SetStyle(ControlStyles.DoubleBuffer, True)
    48. 'Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    49. 'Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.UserPaint, True)
    50. End Sub
    51. ' Die Form überschreibt den Löschvorgang der Basisklasse, um Komponenten zu bereinigen.
    52. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    53. If disposing Then
    54. If Not (components Is Nothing) Then components.Dispose()
    55. End If
    56. MyBase.Dispose(disposing)
    57. End Sub
    58. Protected Overrides Sub Finalize()
    59. '{Destruktor}
    60. MyBase.Finalize()
    61. End Sub
    62. #End Region '{Konstruktor und Destruktor der Klasse}
    63. Public ReadOnly Property CurrentIntervall As Integer
    64. Get
    65. Return FadeIntervall
    66. End Get
    67. End Property
    68. Public ReadOnly Property CurrentWaitIntervall As Integer
    69. Get
    70. Return WaitIntervall
    71. End Get
    72. End Property
    73. ''' <summary>
    74. ''' Fügt der Liste neue News hinzu
    75. ''' </summary>
    76. ''' <param name="News">Die News die hinzugefügt werden sollen</param>
    77. ''' <param name="LinkToNews">Der Link zu den News</param>
    78. ''' <remarks></remarks>
    79. Public Sub AddNews(ByVal News As String, ByVal LinkToNews As String)
    80. Dim NeueNews As New NewsTickerS.NewsString(News, LinkToNews)
    81. _NewsCustom.Add(NeueNews)
    82. End Sub
    83. Public Sub SetIntervall(ByVal NewIntervall As Integer)
    84. FadeIntervall = NewIntervall
    85. End Sub
    86. Public Sub SetWaitIntervall(ByVal NewIntervall As Integer)
    87. WaitIntervall = NewIntervall
    88. End Sub
    89. ''' <summary>
    90. ''' Fängt an mit dem Faden. Trackname _MUSS_ angegeben werde.
    91. ''' </summary>
    92. ''' <remarks>Das ist Remarks</remarks>
    93. Public Sub StartFade()
    94. Fade = True
    95. Dim T As New Threading.Thread(AddressOf Leftfade)
    96. T.Start()
    97. End Sub
    98. Public Sub StopFade()
    99. Fade = False
    100. End Sub
    101. ''' <summary>
    102. ''' Verschiebt die Schrift nach Links
    103. ''' </summary>
    104. ''' <param name="pos">Die Position an der sich die Schrift aktuell befindet</param>
    105. ''' <remarks>Verschiebt die Schrift nach Links. Ist die Schrift links angekommen wird eine Funktion augerufen die die Schrift wieder nach Rechts schiebt</remarks>
    106. Private Sub Leftfade(Optional ByVal pos As Single = 0)
    107. Do
    108. Do While Fade = True
    109. 'Me.Invoke(New DInvalidate(AddressOf InVal))
    110. 'Me.Invalidate(New Region(New Rectangle(0, 0, Me.Width, Me.Height)))
    111. Me.Invalidate()
    112. 'Me.Update()
    113. Threading.Thread.Sleep(FadeIntervall)
    114. Loop
    115. Threading.Thread.Sleep(150)
    116. Loop
    117. End Sub
    118. Private Sub InVal()
    119. Me.Invalidate(New Region(New Rectangle(0, 0, Me.Width, Me.Height)))
    120. Me.Update()
    121. End Sub
    122. Private Sub NewsTicker_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseEnter
    123. Fade = False
    124. End Sub
    125. Private Sub NewsTicker_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseLeave
    126. Fade = True
    127. NSInteger = Nothing
    128. End Sub
    129. Dim NSInteger As Integer
    130. Private Sub NewsTicker_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
    131. MausLocation = e.Location.X
    132. For Each news As NewsTickerS.NewsString In _NewsCustom
    133. For I As Integer = CInt(news.StartPos) To CInt(news.EndPos)
    134. If I = MausLocation Then
    135. Me.Cursor = Cursors.Hand
    136. 'NSInteger = _NewsCustom.IndexOf(news)
    137. 'Me.Invalidate(New Rectangle(news.StartPos, (Me.Height / 2) - (Me.FontHeight / 2), news.StartPos - news.EndPos, Me.FontHeight))
    138. 'Painter.DrawString(news.Text, New Font("Microsoft Sans Serif", 8.25, FontStyle.Underline), Brushes.Green, news.StartPos, news.EndPos)
    139. Exit Sub
    140. Else
    141. 'Fade = True
    142. End If
    143. Next
    144. Next news
    145. End Sub
    146. Public Sub GetPosition()
    147. For Each news As NewsTickerS.NewsString In _NewsCustom
    148. MsgBox("Newsstring = " & news.Text & vbNewLine & _
    149. "Startposition = " & news.StartPos & vbNewLine & _
    150. "Endposition = " & news.EndPos)
    151. Next
    152. End Sub
    153. Private Sub NewsTicker_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    154. 'If Fade = True Then
    155. Try
    156. 'Me.DoubleBuffered = True
    157. Dim diffWith As System.Single = 0
    158. 'CurrentX = CInt(CurrentX)
    159. For Each news As NewsTickerS.NewsString In _NewsCustom
    160. e.Graphics.DrawString(news.Text & " +++", news.Font, Brushes.Black, New PointF(CurrentX + diffWith, (Me.Height / 2) - (Me.FontHeight / 2)))
    161. If _NewsCustom.IndexOf(news) = 0 Then
    162. news.StartPos = CurrentX '+ diffWith
    163. Else
    164. news.StartPos = CurrentX + diffWith
    165. End If
    166. news.EndPos = news.StartPos + e.Graphics.MeasureString(news.Text, news.Font).Width()
    167. diffWith += e.Graphics.MeasureString(news.Text & " +++", news.Font).Width()
    168. Next news
    169. CurrentX -= 1
    170. Threading.Thread.Sleep(FadeIntervall)
    171. If CurrentX <= (diffWith * -1) Then CurrentX = Me.Width
    172. Catch ex As Exception
    173. MsgBox(ex.Message)
    174. End Try
    175. 'Else
    176. ' Try
    177. ' 'Me.DoubleBuffered = True
    178. ' Dim diffWith As System.Single = 0
    179. ' 'CurrentX = CInt(CurrentX)
    180. ' For Each news As NewsTickerS.NewsString In _NewsCustom
    181. ' If _NewsCustom.IndexOf(news) = NSInteger Then
    182. ' e.Graphics.DrawString(news.Text, New Font("Microsoft Sans Serif", 8.25, FontStyle.Underline), Brushes.Black, New PointF(CurrentX + diffWith, (Me.Height / 2) - (Me.FontHeight / 2)))
    183. ' diffWith += e.Graphics.MeasureString(news.Text, New Font("Microsoft Sans Serif", 8.25, FontStyle.Underline)).Width() - 4
    184. ' e.Graphics.DrawString("+++", news.Font, Brushes.Black, New PointF(CurrentX + diffWith, (Me.Height / 2) - (Me.FontHeight / 2)))
    185. ' diffWith += e.Graphics.MeasureString("+++", news.Font).Width()
    186. ' Else
    187. ' e.Graphics.DrawString(news.Text & " +++", news.Font, Brushes.Black, New PointF(CurrentX + diffWith, (Me.Height / 2) - (Me.FontHeight / 2)))
    188. ' diffWith += e.Graphics.MeasureString(news.Text & " +++", news.Font).Width()
    189. ' End If
    190. ' 'If _NewsCustom.IndexOf(news) = 0 Then
    191. ' 'news.StartPos = CurrentX '+ diffWith
    192. ' 'Else
    193. ' 'news.StartPos = CurrentX + diffWith
    194. ' 'End If
    195. ' 'news.EndPos = news.StartPos + e.Graphics.MeasureString(news.Text, news.Font).Width()
    196. ' Next news
    197. ' 'CurrentX -= 1
    198. ' 'Threading.Thread.Sleep(FadeIntervall)
    199. ' If CurrentX <= (diffWith * -1) Then CurrentX = Me.Width
    200. ' Catch ex As Exception
    201. ' MsgBox(ex.Message)
    202. ' End Try
    203. 'End If
    204. End Sub
    205. Private Sub NewsTicker_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick
    206. If e.Button = Windows.Forms.MouseButtons.Left Then
    207. For Each news As NewsTickerS.NewsString In _NewsCustom
    208. For I As Integer = CInt(news.StartPos) To CInt(news.EndPos)
    209. If I = MausLocation Then
    210. System.Diagnostics.Process.Start(news.Link)
    211. Exit Sub
    212. Else
    213. 'Fade = True
    214. End If
    215. Next
    216. Next news
    217. End If
    218. End Sub
    219. End Class
    220. Public Class NewsString
    221. Private _Font As System.Drawing.Font = New System.Drawing.Font("Microsoft Sans Serif", 8, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
    222. Private _ForeColor As System.Drawing.Color = Color.Black
    223. Private _NText As System.String
    224. Private _NLink As System.String
    225. Private _NPosEnd As System.Single = 0
    226. Private _NPosStart As System.Single = 0
    227. Public Property Text() As System.String
    228. Get
    229. Return _NText
    230. End Get
    231. Set(ByVal value As System.String)
    232. _NText = value
    233. End Set
    234. End Property
    235. Public Property Link() As System.String
    236. Get
    237. Return _NLink
    238. End Get
    239. Set(ByVal value As System.String)
    240. _NLink = value
    241. End Set
    242. End Property
    243. Public Property EndPos() As System.String
    244. Get
    245. Return _NPosEnd
    246. End Get
    247. Set(ByVal value As System.String)
    248. _NPosEnd = value
    249. End Set
    250. End Property
    251. Public Property StartPos() As System.String
    252. Get
    253. Return _NPosStart
    254. End Get
    255. Set(ByVal value As System.String)
    256. _NPosStart = value
    257. End Set
    258. End Property
    259. Public Property Font() As System.Drawing.Font
    260. Get
    261. Return _Font
    262. End Get
    263. Set(ByVal value As System.Drawing.Font)
    264. _Font = value
    265. End Set
    266. End Property
    267. Public Property ForeColor() As System.Drawing.Color
    268. Get
    269. Return _ForeColor
    270. End Get
    271. Set(ByVal value As System.Drawing.Color)
    272. _ForeColor = value
    273. End Set
    274. End Property
    275. Public Sub New()
    276. End Sub
    277. Public Sub New(ByVal NewsText As System.String, ByVal NewsLink As String)
    278. Me.ForeColor = Me.ForeColor
    279. Me.Font = Me.Font
    280. Me._NText = NewsText
    281. Me._NLink = NewsLink
    282. End Sub
    283. 'Public ReadOnly Property Width() As System.Single
    284. ' Get
    285. ' Dim g As System.Drawing.Graphics = System.Drawing.Graphics.FromHwnd(NewsTickerS.NewsTicker.Handle)
    286. ' Return CInt(g.MeasureString(Me._NText & " +++ ", Me.Font, 0).Width)
    287. ' End Get
    288. 'End Property
    289. End Class
    290. End Namespace


    Ich rufe dann einfach in einem Button Clickevent "NewsTicker1.StartFade" auf. Und dann gehts los.
    Gibts denn noch ne andere Methode, wie ich so einen Newsticker machen kann ?
    so viel Code ist sicher nicht nötig.
    Das mit dem Threading muß raus, controls könnens net leiden, wenn aus einem Nebenthread reigegrabscht wird. Nimm einen Timer, wenn du regelmäßig die Anzeige verändern willst.
    Und kein eigenes Graphics-Objekt, sondern im Paint-Event bekommst du e.Graphics gestellt - das benutzen.
    Und Usercontrol als Basisklasse ist OverSized, du kannst einfach von Control erben.

    ErfinderDesRades schrieb:

    ...
    Und kein eigenes Graphics-Objekt, sondern im Paint-Event bekommst du e.Graphics gestellt - das benutzen.
    ...

    Hast du dir meinen Code mal angesehen ? Ich arbeite mit dem Paint Event.

    Edit : Dann kann ich den Background aber auch nicht mehr Transparent machen -.-'

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

    habich angesehen, aber so viel Code kannich ohne zu testen, nicht in seiner Funktion durchblicken. Ich fund nur folgende Zeile:

    VB.NET-Quellcode

    1. Private Painter As Graphics = Graphics.FromHwnd(Me.Handle)
    und auch weitere Verwendungen des Objekts.
    Übrigens zum ausmessen von Strings kanns durchaus sinnvoll sein, ausnahmsweise ein selbst erzeugtes Graphics zu nehmen, aber beim Verständnis-Fragment deinse Codes orientiere ich mich auch am Namen - und Painten sollteman wie gesagt nich mit sonem Ding - aber es heißt in deinem Falle Painter.

    Wennichda falsch lag, zeigt das wenigstens, wie wichtig sinnvolle Benamung ist.

    Kann natürlich auch sein, Painter ist ein inzwischen obsoletes Überbleibsel - das würde dann zeigen, wie wichtig es ist, seinen Code aufgeräumt, und mengenmäßig knapp zu halten.

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

    ErfinderDesRades schrieb:

    ...
    das würde dann zeigen, wie wichtig es ist, seinen Code aufgeräumt, und mengenmäßig knapp zu halten.
    ...


    Ich bin das Control doch erstmal am "Debuggen" wenn es hinterher dazu kommt das ich es aktiv verwende dann säubere ich den Code natürlich auch.

    Gibt es denn da noch ne andere Möglichkeit ? Weil das mit dem Timer funktioniert zwar, aber dann hakt das zwischendurch.