ioustinos_sarris
asked on
Drawing lines in vb.net problem
I had a similar problem a few months ago, had to accept the answer in order to be able to post a new one.
So i will describe my situation.
There is not really a need to explain what my data is but when an event is held the program reads some data and creates two rectangles. Into those rectangles i am trying to draw a line into each of them, and onto each line some other vertical lines.
It appears that my lines are drawn and then UNdrawn...(??)
I can see what i drew for a split second and then i get the rectangles with their default background color. Moreover if i place a breakpoint i can normally saw my drawn line, exactly as i wanted it to be. What is that all about??
The event i metioned above is a click event on a button...If i move the code of that click event on the form load event, then i dont event get the temporary drawing...What is that all about No2..??
I am posting the code of the line class which contains both the creation of the rectangle and the line. The instances of tr_line are created with the button click.
So i will describe my situation.
There is not really a need to explain what my data is but when an event is held the program reads some data and creates two rectangles. Into those rectangles i am trying to draw a line into each of them, and onto each line some other vertical lines.
It appears that my lines are drawn and then UNdrawn...(??)
I can see what i drew for a split second and then i get the rectangles with their default background color. Moreover if i place a breakpoint i can normally saw my drawn line, exactly as i wanted it to be. What is that all about??
The event i metioned above is a click event on a button...If i move the code of that click event on the form load event, then i dont event get the temporary drawing...What is that all about No2..??
I am posting the code of the line class which contains both the creation of the rectangle and the line. The instances of tr_line are created with the button click.
Public Class tr_line
Public lineNumber As Integer
Public name As String
Public stops(100) As tr_stop
Public dist As Double
Public graphicsRect As PictureBox
Public gMyGraphics As Graphics ' the drawing surface
Dim pMyPen As Pen ' used to draw the lines
Dim bMyBrush As SolidBrush = New SolidBrush(Color.White) ' used to draw the background
Public label As Label
Public Sub New(ByVal num As Integer, ByVal name As String, ByVal importFileName As String)
Dim tempStop As tr_stop
Me.name = name
Me.lineNumber = num
Dim srFileReader As System.IO.StreamReader
Dim sInputLine As String
srFileReader = System.IO.File.OpenText(importFileName)
sInputLine = srFileReader.ReadLine()
Dim tempStopArray() As String
Dim cnt As Integer = 0
Do Until sInputLine Is Nothing
tempStopArray = sInputLine.Split(";")
tempStop = New tr_stop(tempStopArray(1), CDbl(tempStopArray(2)), CDbl(tempStopArray(3)), CDbl(tempStopArray(4)), cnt + 1)
Me.stops(cnt) = tempStop
cnt += 1
sInputLine = srFileReader.ReadLine()
Loop
Me.dist = stops(cnt - 1).dist
ReDim Preserve stops(cnt - 1)
Me.addGraphicsBox()
Me.drawLineAndStops()
End Sub
Private Sub addGraphicsBox()
Me.graphicsRect = New System.Windows.Forms.PictureBox
Me.graphicsRect.BackColor = System.Drawing.SystemColors.ActiveCaption
Me.graphicsRect.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
Me.graphicsRect.Location = New System.Drawing.Point(Form1.drawVars.X, Form1.drawVars.Y)
Me.graphicsRect.Name = "lineDisplay" & Me.lineNumber
Me.graphicsRect.Size = New System.Drawing.Size(Form1.drawVars.lineRectWidth, Form1.drawVars.lineRectHeight)
Me.graphicsRect.TabIndex = 3
Me.graphicsRect.TabStop = False
Me.label = New Label
Me.label.Name = "label" & Me.lineNumber
Me.label.Location = New System.Drawing.Point(Form1.drawVars.X, Form1.drawVars.Y - 15)
Me.label.AutoSize = True
Me.label.Text = Me.lineNumber
Form1.Controls.Add(Me.graphicsRect)
Form1.Controls.Add(Me.label)
'Friend WithEvents graphicsRect As System.Windows.Forms.PictureBox
Form1.drawVars.oneLineAdded()
End Sub
Private Sub drawLineAndStops()
Dim lineStartMargin As Integer = 10
Dim lineYpos = CInt(Me.graphicsRect.Height * 0.65)
Dim lineWidth = Me.graphicsRect.Width - 2 * lineStartMargin
' set up the drawing surface to draw in the picturebox
gMyGraphics = Me.graphicsRect.CreateGraphics
' set up a pen with the color ' - this pen will be drawing the lines
pMyPen = New Pen(Color.Orange, 5)
' fill the picturebox with a background color
bMyBrush.Color = Color.White
gMyGraphics.FillRectangle(bMyBrush, 0, 0, Me.graphicsRect.Width, Me.graphicsRect.Height)
'gMyGraphics.DrawLine(pMyPen, 0, 0, 100, 50)
gMyGraphics.DrawLine(pMyPen, 0 + lineStartMargin, lineYpos, lineWidth + lineStartMargin, lineYpos)
pMyPen = New Pen(Color.Purple, 3)
Dim pointXToDraw As Integer
For Each st As tr_stop In Me.stops
pointXToDraw = CInt(lineWidth * st.dist / Me.dist) + lineStartMargin
Dim pointYstart As Integer = lineYpos - 12
Dim pointYend As Integer = lineYpos + 12
gMyGraphics.DrawLine(pMyPen, pointXToDraw, pointYstart, pointXToDraw, pointYend)
Next
End Sub
End Class
Public Class tr_line
Public lineNumber As Integer
Public name As String
Public stops(100) As tr_stop
Public dist As Double
Public graphicsRect As PictureBox
Public gMyGraphics As Graphics ' the drawing surface
Dim pMyPen As Pen ' used to draw the lines
Dim bMyBrush As SolidBrush = New SolidBrush(Color.White) ' used to draw the background
Public label As Label
Public Sub New(ByVal num As Integer, ByVal name As String, ByVal importFileName As String)
Dim tempStop As tr_stop
Me.name = name
Me.lineNumber = num
Dim srFileReader As System.IO.StreamReader
Dim sInputLine As String
srFileReader = System.IO.File.OpenText(importFileName)
sInputLine = srFileReader.ReadLine()
Dim tempStopArray() As String
Dim cnt As Integer = 0
Do Until sInputLine Is Nothing
tempStopArray = sInputLine.Split(";")
tempStop = New tr_stop(tempStopArray(1), CDbl(tempStopArray(2)), CDbl(tempStopArray(3)), CDbl(tempStopArray(4)), cnt + 1)
Me.stops(cnt) = tempStop
cnt += 1
sInputLine = srFileReader.ReadLine()
Loop
Me.dist = stops(cnt - 1).dist
ReDim Preserve stops(cnt - 1)
Me.addGraphicsBox()
'Me.drawLineAndStops()
End Sub
Private Sub addGraphicsBox()
Me.graphicsRect = New System.Windows.Forms.PictureBox
Me.graphicsRect.BackColor = System.Drawing.SystemColors.ActiveCaption
Me.graphicsRect.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
Me.graphicsRect.Location = New System.Drawing.Point(Form1.drawVars.X, Form1.drawVars.Y)
Me.graphicsRect.Name = "lineDisplay" & Me.lineNumber
Me.graphicsRect.Size = New System.Drawing.Size(Form1.drawVars.lineRectWidth, Form1.drawVars.lineRectHeight)
Me.graphicsRect.TabIndex = 3
Me.graphicsRect.TabStop = False
Me.label = New Label
Me.label.Name = "label" & Me.lineNumber
Me.label.Location = New System.Drawing.Point(Form1.drawVars.X, Form1.drawVars.Y - 15)
Me.label.AutoSize = True
Me.label.Text = Me.lineNumber
Form1.Controls.Add(Me.graphicsRect)
Form1.Controls.Add(Me.label)
'Friend WithEvents graphicsRect As System.Windows.Forms.PictureBox
Form1.drawVars.oneLineAdded()
End Sub
Private Sub drawLineAndStops(ByVal gMyGraphics As Graphics)
Dim lineStartMargin As Integer = 10
Dim lineYpos = CInt(Me.graphicsRect.Height * 0.65)
Dim lineWidth = Me.graphicsRect.Width - 2 * lineStartMargin
' set up the drawing surface to draw in the picturebox
'gMyGraphics = Me.graphicsRect.CreateGraphics
' set up a pen with the color ' - this pen will be drawing the lines
pMyPen = New Pen(Color.Orange, 5)
' fill the picturebox with a background color
bMyBrush.Color = Color.White
gMyGraphics.FillRectangle(bMyBrush, 0, 0, Me.graphicsRect.Width, Me.graphicsRect.Height)
'gMyGraphics.DrawLine(pMyPen, 0, 0, 100, 50)
gMyGraphics.DrawLine(pMyPen, 0 + lineStartMargin, lineYpos, lineWidth + lineStartMargin, lineYpos)
pMyPen = New Pen(Color.Purple, 3)
Dim pointXToDraw As Integer
For Each st As tr_stop In Me.stops
pointXToDraw = CInt(lineWidth * st.dist / Me.dist) + lineStartMargin
Dim pointYstart As Integer = lineYpos - 12
Dim pointYend As Integer = lineYpos + 12
gMyGraphics.DrawLine(pMyPen, pointXToDraw, pointYstart, pointXToDraw, pointYend)
Next
End Sub
Private Sub me_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles graphicsRect.Paint
drawLineAndStops(e.Graphics)
End Sub
End Class
you got me there idle mind, didn't see your post
No problem...glad we came to the same conclusion. =)
ASKER
I see.
It seems to be working but i do not get some things.
How could i draw that line based on a event??
For example, i want to draw the rectangle when the program loads and draw the line when the user clicks on a button at any other time.
What should i do? Trigger the paint event for the graphicsRect ?
And what if i have a circle to draw as well in the rectangle as well which should be called by another event? The paint event does not seem to be taking any user define parameters
Thanks for any info you can provide me with!
It seems to be working but i do not get some things.
How could i draw that line based on a event??
For example, i want to draw the rectangle when the program loads and draw the line when the user clicks on a button at any other time.
What should i do? Trigger the paint event for the graphicsRect ?
And what if i have a circle to draw as well in the rectangle as well which should be called by another event? The paint event does not seem to be taking any user define parameters
Thanks for any info you can provide me with!
ASKER
Moreover...
I really need to get a hold on how this is working or else i am going to have problems in the fututre
I just tried to add an icon on the container drawing surface through another class.
In order to do that i added this line to the me_paint function
and later on i tried to do this through another class that holds an instance of the line object
I get a weird exception Message="Parameter is not valid."
thanks again
I really need to get a hold on how this is working or else i am going to have problems in the fututre
I just tried to add an icon on the container drawing surface through another class.
In order to do that i added this line to the me_paint function
Me.lineGraphics = e.Graphics
and later on i tried to do this through another class that holds an instance of the line object
Me.line.lineGraphics.DrawIcon(Me.theIcon, 20, 20)
I get a weird exception Message="Parameter is not valid."
thanks again
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Aha. i see.
TO see that i got it right.
Everything that is "Drawn" is actually put in a buffer which will be implemented when the Refresh() function is called.
In order to make the refresh do different things every time i must have an instance of an object (or some variables in that matter) which has to be of global scope. Right?.
Would it be better if i extended the pictureBox class?
TO see that i got it right.
Everything that is "Drawn" is actually put in a buffer which will be implemented when the Refresh() function is called.
In order to make the refresh do different things every time i must have an instance of an object (or some variables in that matter) which has to be of global scope. Right?.
Would it be better if i extended the pictureBox class?
That's exactly right. The info about what has to be drawn must be stored somewhere. In the simple example the Form was handling the painting based on the data within the data class, but you can also make the class receive a Graphics in its own "paint" method and the class instance would draw itself onto that graphics based on the data within itself. So in the Paint() event you'd iterate over all the instances and pass the "e.Graphics" into each one so that it could draw itself.
You can either extend the PictureBox or create a new USERCONTROL and handle its Paint() event.
You can either extend the PictureBox or create a new USERCONTROL and handle its Paint() event.
So move the code in drawLineAndStops() to the Paint() event and change:
gMyGraphics = Me.graphicsRect.CreateGrap
To:
gMyGraphics = e.Graphics
You can either use AddHandler() to wire up the Paint() event or declare graphicsRect as WithEvents so you can use a Handles clause.