views:

59

answers:

3

so i got this piece of code. (currPosX is defined earlier)

while (earliestDate < DateTime.Today)
        {
            currPosX = currPosX + 5;
            e.Graphics.DrawLine(Pens.Black, currPosX, 0, currPosX, 10);

            earliestDate = earliestDate.AddDays(1);
        }

the graphics don't draw. it's really weird, since this only happens when the condition statement is a date comparison. I debugged, and it does go in the loop, and the values are messed with (currPosX for example). But, no display. one more weirdness, if I add a MessageBox.Show("blabla") in the loop, the message box pops up, and graphics are drawn. what's going on here?

EDIT: just to remind you guys, when it's a non-datetime condition, it works. meaning that this code works. it does display a series of lines

int i = 0;

        while(i < 10)
        {
            currPosX = currPosX + 5;
            e.Graphics.DrawLine(Pens.Black, currPosX, 0, currPosX, 10);
            i++;
        }
A: 
Danny Varod
+2  A: 

As your tests indicate, the issue has nothing to do with comparing DateTime's. Since your code is entering the loop, and you know the painting is being done, something else must be going on. We'll probably need to see more code to identify the problem

Trying to step through painting code is useless. The fact that the debugger and application window trade focus will completely screw things up. You are better off using tracepoints, not breakpoints.

But here's some possibilities:

  • Are you sure your coordinates are in the control's visible client area?
  • Are you doing the above in the control's Paint event?
  • Are you remembering to invalidate the control using the Invalidate or Refresh method?
  • Are you painting on the UI thread?
  • Do you have any non-standard control styles set?

UPDATE In response to your edit:

Your problem is that earliestDate will keep creeping forward because you are modifying it in your Paint event and the value will persist between Paint events. Paint events occur repeatedly every time the control is invalidated. You have two options.

  1. Copy earliestDate to a local variable in the Paint event and use that
  2. Reset earliestDate back to its starting value at the end of the event.

I suggest option 1.

Josh Einstein
yes, visible area. yes, in the Paint event. invalidate or refresh doesn't work, nothing happens. I don't know what UI thread is. I don't know what control style is. check my edit
jello
I updated my answer in response to your edits.
Josh Einstein
I used your #1 solution, and it works. thx
jello
+3  A: 

I did a simple test project that just has a form with no controls on it (the code is below). As you can see I added a little code in the constructor to initialize the earliest data so that the while loop in the Paint event will be executed once. Also hard coded the currPos value.

If you run this, it will draw a vertical line as expected. But if you do anything that invalidates the Graphics (for example, minimize and restore the form), it will not redraw he graphics. So, it draws it once, but will not draw again for 24 hours!

public partial class Form1 : Form
{
    DateTime earliestDate;
    public Form1()
    {
        earliestDate = DateTime.Now;
        earliestDate = earliestDate.AddDays(-1);
        InitializeComponent();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        while (earliestDate < DateTime.Today)
        {
            float currPosX = 0;
            currPosX = currPosX + 5;
            e.Graphics.DrawLine(Pens.Black, currPosX, 0, currPosX + 5, 10);

            earliestDate = earliestDate.AddDays(1);
        } 
    }
}
Malcolm Post
+1 Brilliant! That sounds like it would be the problem.
Zach Johnson
thx, but your code is not good for me, because i have 2 panels. the top panel has a scroll bar on it, and when you scroll it, the bottom panel(which contains the graphics) must follow. so, unless I'm wrong, the control needs to redraw every time I scroll the top panel
jello
You are right that you need to redraw every time. This code wasn't intended to solve the problem - it was just showed a test that confirms that you can't skip the redrawing.
Malcolm Post