1

I am busy developing an C# win form application, that draws a graphical representation of a database structure in a hierarchical structure.

Everything is working fine, I just have a problem with scrolling. It has a bad flickering problem.

I have researched the following:

C# graphics flickering

Call Invalidate() when you want to refresh the surface (has helped a lot but still a little of a lag)

Also to set DoubleBuffered property to True (Problem with this I get an ArgumentException thrown with message "Parameter is not valid.". But I can set DoubleBuffered to true on my main form)

Detail on my design

I have two class Node and Link they both have GraphicsPath members, and they both have a public void Draw(Graphics g) method to draw themselves.

I also have a user control call StructureMap that has overridden the protected override void OnPaint(PaintEventArgs e) method, to loop through every Node calling it's draw function. The looping is simple because the Parent Node is link to the children nodes by a Link object. All I have to do is call the parent node's draw method, and all its children nodes are also redrawn.

I am also preforming Hit testing the same way.

Is there maybe a better way? Why can't I have DoubleBuffered set to true on my user control?

PS: This is my first post, let me know how I did?

Community
  • 1
  • 1
ZioN
  • 550
  • 2
  • 11
  • 35

3 Answers3

1

The DoubleBuffered ArgumentException is probably caused due to the fact that you somewhere dispose the graphics object.

Also refer to this article; What could cause Double Buffering to kill my app?

Community
  • 1
  • 1
Gerald Versluis
  • 30,492
  • 6
  • 73
  • 100
  • You are right, that solved the DoubleBuffered issue. I thought you needed to Dispose the graphics object to prevent memory leaks. But with DoubleBuffered on there is still a lag in scrolling. – ZioN Jul 06 '12 at 11:53
  • @ZioN: that's because your paint routine is slow and that's an entirely different matter. feel free to ask another question for that. – Sedat Kapanoglu Jul 06 '12 at 11:59
0

Your flickering sound like it is caused by the amount of processing you have to do to draw the image.

One way to alleviate this is to draw your model to an offscreen bitmap, then your paint/scroll etc just draw that bitmap to the screen.

Then only update the bitmap if your model changes.

Mesh
  • 6,262
  • 5
  • 34
  • 53
  • I think bitmap can help a lot. I also want to know can you do hit testing with bitmaps? As I also want to animate my objects, want to be able to select and un-select them? – ZioN Jul 07 '12 at 13:31
  • One way is to attach your image to PictureBox control, position the picture box inside a Panel with AutoScroll enabled. Use the various mouse events to get the position of mouse interactions. – Mesh Jul 09 '12 at 08:21
  • I will have a look at this in the future, as for now I just working with my current design, because using bitmaps and PictureBox will be a redesign. I think I will consider that in version 2 ;) – ZioN Jul 12 '12 at 16:30
0

Using bitmap as a background image will reduce flickering. Maybe like this :

 private Bitmap _backBuffer;
 private void Form1_Paint(object sender, PaintEventArgs e)
 {
      if (_backBuffer == null)
        {
            _backBuffer = new Bitmap(Form1.Width, Form1.Height, PixelFormat.Format32bppRgb);
        }
        Graphics g = Graphics.FromImage(_backBuffer);

        g.SmoothingMode = SmoothingMode.HighQuality;

        drawSomething(g);

        //Copy the back buffer to the screen
        e.Graphics.DrawImageUnscaled(_backBuffer, 0, 0);
        Form1.BackgroundImage = _backBuffer;
 }
Faruk
  • 5,438
  • 3
  • 30
  • 46