mandelbrot Posted May 17, 2006 Posted May 17, 2006 (edited) Hi All, I've written a control which displays information from a specific class in a similar (but not the same) manner as a TreeView. Originally I started by drawing out the control in the same way that I would with a webpage, but found this exceptionally slow. Now, I've loaded all data into memory, and run through the tree structure reading the appropriate data from the nested classes and drawing to screen using graphics methods. This should be much faster, but I'm getting no results... Here's the basic drawing routines - I'd appreciate any help I can get... 'Draw the tree... Private Sub DrawTree(ByVal pOccurence As Occurence, ByVal pGraphics As Graphics) 'Dimensions... Dim currPen As New Pen(_EventColor, 2) Dim currSize As Size Dim bracketT As Integer = -1 Dim bracketB As Integer = -1 Dim bracketL As Integer = -1 Dim bracketR As Integer = -1 Dim drawPoints(3) As Point 'Initialise... If Not isDrawing Then linePointer = 0 pGraphics.Clear(Me.BackColor) Controls.Clear() clickZones.Clear() End If isDrawing = True 'Draw the starting text... DrawText("Started: " & pOccurence.Started.ToString("HH:mm") & " - [" & pOccurence.Type.Name & "] " & pOccurence.Title, pOccurence, pGraphics) DrawText(pOccurence.Description, pOccurence, pGraphics) 'Check for and draw children... If pOccurence.Count > 0 Then Dim currOcc As Occurence For Each currOcc In pOccurence DrawTree(currOcc, pGraphics) Next End If 'Draw the end text of the class... If pOccurence.Ended = Util.defaultDate Then DrawText("Still active...", pOccurence, pGraphics) Else DrawText("Ended: " & pOccurence.Ended.ToString("HH:mm"), pOccurence, pGraphics) End If 'Draw the bracket... bracketT = CType(linePointer * ySize + ySize / 2, Integer) bracketB = CType(linePointer * ySize + ySize / 2, Integer) bracketL = CType(pOccurence.NodeLevel * xSize + xSize / 4, Integer) bracketR = CType(bracketL + xSize / 2, Integer) drawPoints(0) = New Point(bracketR, bracketT) drawPoints(1) = New Point(bracketL, bracketT) drawPoints(2) = New Point(bracketL, bracketB) drawPoints(3) = New Point(bracketR, bracketB) 'Check to see if the current occurence is selected... If _Value Is pOccurence Then currPen.Color = _HighlightColor pGraphics.DrawRectangle(currPen, New Rectangle(bracketL - 4, bracketT - 4, bracketR + 4, bracketB + 4)) End If 'Check which color we should be using... Select Case pOccurence.Class.Name Case "Event" currPen.Color = _EventColor Case "Action" currPen.Color = _ActionColor Case "Causality" currPen.Color = _CausalityColor End Select pGraphics.DrawLines(currPen, drawPoints) clickZones.Add(New Zone(pOccurence, bracketL - 4, bracketT - 4, bracketR + 4, bracketB + 4)) 'Close out... isDrawing = False End Sub 'Draw the text... Private Sub DrawText(ByVal pText As String, ByVal pOccurence As Occurence, ByVal pGraphics As Graphics) 'Dimensions... Dim currpen As New Pen(_HighlightColor) Dim currSize As SizeF = pGraphics.MeasureString(pText, Me.Font) Dim currBrush As New Drawing.SolidBrush(_EventColor) Dim currRegion As New Rectangle(CType(pOccurence.NodeLevel * xSize, Integer), _ CType(linePointer * ySize, Integer), _ CType(currSize.Width, Integer), _ CType(currSize.Height, Integer)) 'Check to see if the current occurence is selected... If _Value Is pOccurence Then currPen.Color = _HighlightColor pGraphics.DrawRectangle(currpen, currRegion) End If 'Check which color we should be using... Select Case pOccurence.Class.Name Case "Event" currBrush.Color = _EventColor Case "Action" currBrush.Color = _ActionColor Case "Causality" currBrush.Color = _CausalityColor End Select 'Draw the start of the object... pGraphics.DrawString(pText, Me.Font, currBrush, pOccurence.NodeLevel * xSize, linePointer * ySize) clickZones.Add(New Zone(currRegion, pOccurence)) 'Increment the line counter... linePointer += 1 End Sub Just while I think on - the DrawTree routine is initially called from the Invalidate routine; pGraphics being set to Me.CreateGraphics, and disposed on the line after the call... 'Invalidate the current control... Public Overloads Sub Invalidate() Me.Invalidate(New Rectangle(0, 0, Me.Width, Me.Height)) If Not _StartOfDay Is Nothing Then Dim pageGfx As Graphics = Me.CreateGraphics DrawTree(_StartOfDay, pageGfx) pageGfx.Dispose() End If End Sub Thanks in advance, Paul. Edited May 17, 2006 by mandelbrot Quote
Leaders snarfblam Posted May 20, 2006 Leaders Posted May 20, 2006 I don't have a direct answer to your question but you need to realize that the Graphics class is a bit slower than GDI. This is particularly applicable with blitting functions, especially when many small images are drawn, as opposed to a few large images. Depending on your exact needs you might want to consider moving to GDI or double buffering your control. Quote [sIGPIC]e[/sIGPIC]
mandelbrot Posted May 22, 2006 Author Posted May 22, 2006 (edited) Thanks for your response, marble. I'm not so worried about the speed - I used to draw the screen using controls (i.e. image controls and labels), which is very slow! I'm having to revert to this until I can figure out the graphics side of things. The idea behind the routines above is that it reads the tree using a recursive function call and drawing all the appropriate text, but only draws the brackets in (literally looking like a square bracket [ ) as the recurssion unwraps. The image attached shows what I'm trying to achieve (this is a working image from the current implementation). Paul. Edited May 22, 2006 by mandelbrot Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.