Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / January 2008

Tip: Looking for answers? Try searching our database.

DrawString Graphics problem

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Brian Ward - 10 Jan 2008 16:40 GMT
I am trying to get to grips with some basic graphics, being new to C#.
I have this code (see below) in a simple project .. when I run it 6 text
strings are drawn, as I expected .. but this happens twice .. once with
a grey background and once with the white one.
Clearly I am missing something fundamental here.
Can anyone please explain.
TIA
===
Brian
=====
private void Form1_Paint(object sender, PaintEventArgs e)
{
           this.BackColor = Color.White;
           Graphics g = e.Graphics; // get a graphics object
           Font ft = new Font("Arial", 30);  // create a font ft
           Brush br = new SolidBrush(Color.Tomato);  // create a brush br
           int y = 20;
           for (int i = 0; i < 6; i++)
           {
               g.DrawString("Brian is texting a Window", ft, br, 30, y);
               y += 50;
               System.Threading.Thread.Sleep(1000);  // pause for 1 sec
           }
}
Peter Duniho - 10 Jan 2008 19:35 GMT
> I am trying to get to grips with some basic graphics, being new to C#.
> I have this code (see below) in a simple project .. when I run it 6 text
> strings are drawn, as I expected .. but this happens twice .. once with
> a grey background and once with the white one.
> Clearly I am missing something fundamental here.

Your event handler is wrong.

First, you created a Font and a Brush, both of which need to be disposed  
of when you're done with them.

Second, you _never_ ever want to do anything in a paint handler except  
anything _directly_ related to drawing to the control.  Calling  
Thread.Sleep() is a _huge_ no-no.  So is changing the background color for  
the control.

I believe that what's going on in your case is that the change to the  
background color won't take effect until you return from the paint  
handler, because nothing else can happen to the control until the paint  
handler is done.  So you're stuck in the paint handler, drawing the string  
six times using the old background color.  Then you finally exit, which  
allows the background color change to take effect, at which point another  
redraw is signaled, causing you to draw the string six more times.

The basic .NET Forms painting outline is as follows:

    * Write a paint handler (or override OnPaint()) that, given some state  
for your control and/or data can always draw the complete state

    * Write some code elsewhere that manages the state.  For animation,  
this usually involves some sort of timing mechanism that updates the state  
at suitable intervals.

    * Any time the state changes, call Control.Invalidate() to signal to  
the framework that the display of that state needs to be updated.  This  
will result in your paint handler being called, at which time it will  
completely draw the current state.

It is completely inappropriate to manage the state and/or timing of  
animation from within the paint handler.  Do not ever do this.

Pete
Chris Dunaway - 10 Jan 2008 21:02 GMT
> I am trying to get to grips with some basic graphics, being new to C#.
> I have this code (see below) in a simple project .. when I run it 6 text
[quoted text clipped - 21 lines]
>
> }

To add to what Peter has said, here is a site that might help you:

http://www.bobpowell.net

Chris
Bob Powell [MVP] - 11 Jan 2008 10:56 GMT
Funny, I was just about to suggest that myself ;-)

Signature

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.

>> I am trying to get to grips with some basic graphics, being new to C#.
>> I have this code (see below) in a simple project .. when I run it 6 text
[quoted text clipped - 28 lines]
>
> Chris
Chris Dunaway - 11 Jan 2008 21:09 GMT
On Jan 11, 4:56 am, "Bob Powell [MVP]" <b...@spamkillerbobpowell.net>
wrote:
> Funny, I was just about to suggest that myself ;-)
>
[quoted text clipped - 44 lines]
>
> > Chris

Hi Bob,

I love your site!  When will your book be out?  ;)

I noticed on your site that you have started a WPF faq.  Have had a
chance to use WPF much?  What are your impressions of it compared to
GDI and GDI+ ?

Cheers,

Chris
Brian Ward - 12 Jan 2008 09:27 GMT
Thanks for all this help .. Bob's site looks really good.
One more thing. I have another problem (always another!)
I am using protected override bool ProcessCmdKey to control the movement
of this circle (see below) by adjusting x and y values .. it works fine,
but I also want the circle to leave a trace behind it as it moves  .. I
would think that writing to a Bitmap would be the thing, but I can't
seem to figure out how.
Any help again much appreciated
==
Brian
==

private void Form1_Paint(object sender, PaintEventArgs e)
{
           Graphics g = e.Graphics;
           g.FillEllipse(Brushes.Blue, x, y, 20, 20);
           g.Dispose()        
}
Peter Duniho - 12 Jan 2008 18:33 GMT
> [...]
> but I also want the circle to leave a trace behind it as it moves  .. I
> would think that writing to a Bitmap would be the thing, but I can't
> seem to figure out how.
> Any help again much appreciated

Well, the basic idea would be to create a Bitmap instance into which you  
draw, using Graphics.FromImage() to get a Graphics instance you can use  
for drawing the circle, then in your Paint handler draw the Bitmap instead  
of the circle.

Assuming the size of your control never changes, this may be the easiest.  
If you want to handle changes in the control size gracefully it gets more  
complicated, at least partly just because you then need to decide what  
behavior is "correct" for your application.

You could save the circles into a Metafile instead, which introduces its  
own complexities but can avoid the resizing issue.  Alternatively, you  
could just keep your own list of circles as you add them, drawing all of  
them one by one each time the control needs to be painted.  And of course  
you could use some combination of the above, such as using a Bitmap most  
of the time, but still storing a list of the circles so that you can  
recreate a new Bitmap at arbitrary sizes as the control changes without  
worrying about how best to preserve previously drawn circles.

Basically, for small numbers of circles, just storing the circles  
themselves is easiest and more efficient.  As the number of circles goes  
up, a solution that uses only a Bitmap becomes more efficient.  There's a  
large area of wiggle room in the middle where you can pretty much do it  
however you prefer.  :)

Pete
Peter Duniho - 14 Jan 2008 04:28 GMT
I was looking at this thread in review for a reply elsewhere, and I took  
another look at this post.  I'm embarassed that I didn't notice the  
obvious bug, especially since it might have been introduced as a result of  
a misunderstanding of a comment I made earlier.  In particular:

> [...]
>  private void Form1_Paint(object sender, PaintEventArgs e)
[quoted text clipped - 3 lines]
>             g.Dispose()
> }

Do _not_ dispose the Graphics instance.  It is good and correct to dispose  
objects that are disposable and which you created in your own code.  But  
the Graphics instance is passed to you in the event args and must remain  
valid for other Paint event handlers.  Don't call Dipose() on it.

Sorry for not noticing this earlier.

Pete

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.