VB 2005 graphics concepts

A

AWW

XP VB 2005 drawing line graphics in a PictureBox - from a simple
minded former FORTRAN programmer.
The help examples have the graphics drawing code (lines & rectangles)
in the PictureBox paint event handler - making it a static display.
But I don't want a static display - I want to draw dynamic data so how
do I get the data to the event handler - if I need to do that.
I have also done line drawings on the Form but those drawings have an
annoying habit of vanishing sometimes.
Is VB 2005 just not intended for line graphics - or am I as dense as a
lead baloon? Thanks for info or Internet references.
 
A

Armin Zingler

XP VB 2005 drawing line graphics in a PictureBox - from a simple
minded former FORTRAN programmer.
The help examples have the graphics drawing code (lines &
rectangles) in the PictureBox paint event handler - making it a
static display. But I don't want a static display - I want to draw
dynamic data so how do I get the data to the event handler - if I
need to do that. I have also done line drawings on the Form but
those drawings have an annoying habit of vanishing sometimes.
Is VB 2005 just not intended for line graphics - or am I as dense as
a lead baloon? Thanks for info or Internet references.

I don't see the problem. You don't have to draw the same each time you draw.
If you want to update the display, call the control's Invalidate method. The
paint event will be raised. I suggest deriving your control from Picturebox,
or directly from Control, add a property that represents the data to be
painted, and each time the property changes, your control can call it's own
Invalidate method. Or you can still call Invalidate from outside. Depends on
what and when you want to paint.


Armin
 
C

Chris Dunaway

XP VB 2005 drawing line graphics in a PictureBox - from a simple
minded former FORTRAN programmer.
The help examples have the graphics drawing code (lines & rectangles)
in the PictureBox paint event handler - making it a static display.
But I don't want a static display - I want to draw dynamic data so how
do I get the data to the event handler - if I need to do that.
I have also done line drawings on the Form but those drawings have an
annoying habit of vanishing sometimes.
Is VB 2005 just not intended for line graphics - or am I as dense as a
lead baloon? Thanks for info or Internet references.

See this site:

www.bobpowell.net
 
J

Jack Jackson

XP VB 2005 drawing line graphics in a PictureBox - from a simple
minded former FORTRAN programmer.
The help examples have the graphics drawing code (lines & rectangles)
in the PictureBox paint event handler - making it a static display.
But I don't want a static display - I want to draw dynamic data so how
do I get the data to the event handler - if I need to do that.
I have also done line drawings on the Form but those drawings have an
annoying habit of vanishing sometimes.
Is VB 2005 just not intended for line graphics - or am I as dense as a
lead baloon? Thanks for info or Internet references.

This is not a VB 2005 thing, it is a Windows thing. Windows (at least
pre-Vista) does not have a bitmap for what is displayed in a window.
Whenever Windows needs to repaint a window, for example when part or
all of a window is uncovered, it invalidates part or all of the window
and sends a Paint message. It is then up to the application to redraw
the window.

You need to draw everything in the Paint event. If you draw outside
of Paint, then at some time later when Windows redraws your window
what you drew will be overwritten.

When you make a change that affects the screen, Invalidate that part
of the window which will result in a Paint event. This means you need
to keep all of the information that will allow your Paint event
handler to redraw the window.
 
A

AWW

I don't see the problem. You don't have to draw the same each time you draw.
If you want to update the display, call the control's Invalidate method. The
paint event will be raised. I suggest deriving your control from Picturebox,
or directly from Control, add a property that represents the data to be
painted, and each time the property changes, your control can call it's own
Invalidate method. Or you can still call Invalidate from outside. Depends on
what and when you want to paint.


Armin
OK several dumb (outdated programmer) questions:
by derive - you mean - Dim Box1 as New PictureBox - right?
I have no clue how to add a property to a Control and nothing in help
that I can find (likely not knowing where to look) - can you explain?

the following example works:
Inports System.Drawing
Imports System.Windows.Forms
Public Class Form1
Private sub Form1_Load(ByVal sender as Object, ByVal e as
System.EventArgs) Handles MyBase.Load
DrawEllipse()
End Sub

Private Sub DrawEllipse()
Dim myPen as New Pen(Color.Red)
Dim g as Graphics
g = Me.CreateGraphics()
g.DrawEllipse(myPen, New Rectangle(0, 0, 200, 300))
myPen.Dispose()
g.Dispose()
End Sub
End Class
Question: If I have no dragging or overlapping - just drawing in
various separate parts of the Form - do I need to worry about the
paint event? or OnPaint?
Since it works - why would some of my graphics vanish seemingly at
random? because I did not dispose the pen and g/Graphics properly? or
because Windows does a repaint at random?
Thanks for anything you may add.
 
A

Armin Zingler

OK several dumb (outdated programmer) questions:

Isn't a dumb question. :)
by derive - you mean - Dim Box1 as New PictureBox - right?

No, I mean inherit from Picturebox, or better from Control. See example
below.

I have no clue how to add a property to a Control and nothing in
help that I can find (likely not knowing where to look) - can you
explain?

the following example works:
Inports System.Drawing
Imports System.Windows.Forms
Public Class Form1
Private sub Form1_Load(ByVal sender as Object, ByVal e as
System.EventArgs) Handles MyBase.Load
DrawEllipse()
End Sub

In Form_Load, drawing doesn't make sense because the Form isn't visible yet.
Question: If I have no dragging or overlapping - just drawing in
various separate parts of the Form - do I need to worry about the
paint event? or OnPaint?

Yes, you have to paint in OnPaint or in the Paint event.
Since it works - why would some of my graphics vanish seemingly at
random? because I did not dispose the pen and g/Graphics properly?
or because Windows does a repaint at random?
Thanks for anything you may add.

Add the following class to a new project, compile it, open Form1 in designer
and add an instance of the control from the toolbox. It's a simple painting
example. Run it, and each time you click the left mouse button, a new point
is added to the list of Points. Afterwards, Invalidate is called in order to
refresh the control.


Public Class MyControl
Inherits Control

Private f_Points As New List(Of Point)

Sub New()

SetStyle( _
ControlStyles.AllPaintingInWmPaint _
Or ControlStyles.UserPaint _
Or ControlStyles.ResizeRedraw _
Or ControlStyles.OptimizedDoubleBuffer, _
True _
)

End Sub
Protected Overrides Sub OnPaint( _
ByVal e As System.Windows.Forms.PaintEventArgs)

e.Graphics.Clear(Color.Black)

For Index = 1 To f_Points.Count - 1
e.Graphics.DrawLine( _
Pens.White, f_Points(Index - 1), f_Points(Index) _
)
Next

End Sub
Protected Overrides Sub OnMouseDown( _
ByVal e As System.Windows.Forms.MouseEventArgs)

MyBase.OnMouseDown(e)

If e.Button = Windows.Forms.MouseButtons.Left _
AndAlso Control.ModifierKeys = Keys.None Then

f_Points.Add(New Point(e.X, e.Y))
Invalidate()
End If

End Sub

Protected Overrides Sub OnPaintBackground( _
ByVal pevent As System.Windows.Forms.PaintEventArgs)

'intentionally empty. All painting is done in OnPaint

End Sub

End Class



Armin
 
A

AWW

Add the following class to a new project, compile it, open Form1 in designer
and add an instance of the control from the toolbox. It's a simple painting
example. Run it, and each time you click the left mouse button, a new point
is added to the list of Points. Afterwards, Invalidate is called in order to
refresh the control.


Public Class MyControl
Inherits Control

Private f_Points As New List(Of Point)

Sub New()

SetStyle( _
ControlStyles.AllPaintingInWmPaint _
Or ControlStyles.UserPaint _
Or ControlStyles.ResizeRedraw _
Or ControlStyles.OptimizedDoubleBuffer, _
True _
)

End Sub
Protected Overrides Sub OnPaint( _
ByVal e As System.Windows.Forms.PaintEventArgs)

e.Graphics.Clear(Color.Black)

For Index = 1 To f_Points.Count - 1
e.Graphics.DrawLine( _
Pens.White, f_Points(Index - 1), f_Points(Index) _
)
Next

End Sub
Protected Overrides Sub OnMouseDown( _
ByVal e As System.Windows.Forms.MouseEventArgs)

MyBase.OnMouseDown(e)

If e.Button = Windows.Forms.MouseButtons.Left _
AndAlso Control.ModifierKeys = Keys.None Then

f_Points.Add(New Point(e.X, e.Y))
Invalidate()
End If

End Sub

Protected Overrides Sub OnPaintBackground( _
ByVal pevent As System.Windows.Forms.PaintEventArgs)

'intentionally empty. All painting is done in OnPaint

End Sub

End Class


Armin
Ok thanks - it works the way you said but I want to fill a number of
rectangles with line data so, I gather, one way is to set up the line
drawings in multiple MyComponent instances and fill the f_Points lists
with the data for drawing at OnPaint - right? No vanishing then -
right?
Problem - no clue on accessing the MyComponent instances f_Points
lists - can you help with my (last?) problem? Thanks again.
 
A

Armin Zingler

AWW said:
Ok thanks - it works the way you said but I want to fill a number of
rectangles with line data so, I gather, one way is to set up the line
drawings in multiple MyComponent instances and fill the f_Points lists
with the data for drawing at OnPaint - right? No vanishing then -
right?
Right.

Problem - no clue on accessing the MyComponent instances f_Points
lists - can you help with my (last?) problem? Thanks again.

Add a property: (untested)

public property Points As List(Of Point)
Set(byval value as list (of point))
f_points = value
invalidate
end set
Get
return f_points
end get
end property

And, in OnPaint, add this line after graphics.clear:

if f_points is nothing then return

You can now set the Points property to the list you want to paint.
In addition, you may want to change the type List(Of) to IList(Of).
And, you may also want to apply the DesignerSerializationVisibility
attribute to the property. And,...


Armin
 
A

AWW

Add a property: (untested)

public property Points As List(Of Point)
Set(byval value as list (of point))
f_points = value
invalidate
end set
Get
return f_points
end get
end property

And, in OnPaint, add this line after graphics.clear:

if f_points is nothing then return

You can now set the Points property to the list you want to paint.
In addition, you may want to change the type List(Of) to IList(Of).
And, you may also want to apply the DesignerSerializationVisibility
attribute to the property. And,...


Armin
Ok, I took only part of your advice - I changed the storage to an
array since my data will be in fixed length arrays - then I just put a
Public Sub in MyControl and transferred the data. It works.

Thanks again - you helped me understand, for me, a confusing area that
is NOT (that I can find) covered clearly in help or via Google.
 
A

AWW

OK I have one more (stupid?) question,
the program was working and drawing some random lines on the screen
using MyControl (I had dragged MyControl component onto the screen).
My screen now contained a Quit (exit program) button and MyControl.

So I dragged another button (DrawIt) onto the screen to redraw
different random lines and that works but Quit vaishes - and the IDE
no longer works properly.
Can you shed any light? Thanks again - I hope.
- Frustrated -
 
A

Armin Zingler

AWW said:
OK I have one more (stupid?) question,
the program was working and drawing some random lines on the screen
using MyControl (I had dragged MyControl component onto the screen).
My screen now contained a Quit (exit program) button and MyControl.

So I dragged another button (DrawIt) onto the screen to redraw
different random lines and that works but Quit vaishes -

Vaishes? Vanishes? In what way?
and the IDE
no longer works properly.

In what way?
Can you shed any light? Thanks again - I hope.
- Frustrated -

I know too little to be able to give an answer.

Armin
 
A

AWW

Vaishes? Vanishes? In what way?


In what way?


I know too little to be able to give an answer.

Armin
OK, no wonder you were confused by my confusion.
I put the Overrides you mentioned in the main (base?) class and then
drew the lines in a new Rectangle and it works fine (and refreshes
fine) - still don't understand why the IDE went haywire but won't
worry about it for now. Really appreciate that help.

'Help' and MSDN talk about a BehaviorService in .Net 2.0 that looks
like it could be useful but
Imports System.Windows.Forms.Design.Behavior
fails as does any reference to any of the parts. I have .Net 2.0 so I
should have that - right? Any comment?
Thanks and sorry to be so obtuse.
 
J

Jack Jackson

OK, no wonder you were confused by my confusion.
I put the Overrides you mentioned in the main (base?) class and then
drew the lines in a new Rectangle and it works fine (and refreshes
fine) - still don't understand why the IDE went haywire but won't
worry about it for now. Really appreciate that help.

'Help' and MSDN talk about a BehaviorService in .Net 2.0 that looks
like it could be useful but
Imports System.Windows.Forms.Design.Behavior
fails as does any reference to any of the parts. I have .Net 2.0 so I
should have that - right? Any comment?
Thanks and sorry to be so obtuse.

You are confusing the namespace with the assembly.

Look at the documentation for BehaviorService class:
<http://msdn.microsoft.com/en-us/lib...s.design.behavior.behaviorservice(VS.80).aspx>

It says:
Namespace: System.Windows.Forms.Design.Behavior
Assembly: System.Design (in system.design.dll)

You need to add a reference to your project for the assembly
(System.Design), and then either:
Imports System.Windows.Forms.Design.Behavior
or completely qualify the name:
Dim xx As System.Windows.Forms.Design.Behavior.BehaviorService

However, this appears to be only for design-time use.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top