1

Can anyone please advise:

I have a Windows form user control of my own creation which I've placed on a standard WinForm. The code of the user control is trivial:

protected override void OnPaintBackground(PaintEventArgs pevent)
{
}

and

private void MyUserControl_Paint(object sender, PaintEventArgs e)
{
    Graphics clientDC = this.CreateGraphics();

    Bitmap bitmap = new Bitmap(Bounds.Width, Bounds.Height);

    Graphics graphicsSurface = Graphics.FromImage(bitmap);

    graphicsSurface.Clear(Color.Black);

    clientDC.DrawImage(bitmap, 0, 0);

    GC.Collect();
}

On the resize event of the main WinForm I resize the user control to fill the entire form as so:

MyUserControl.Bounds = new Rectangle(0, 0, ClientRectangle.Width, ClientRectangle.Height);

Good. It all works fine. As I drag a corner of the main form around the user control fills the form with it's black rectangle. No Problems.

Now, I place a scroll bar in my control and on resize I keep it "docked" to the right hand side. Relevant code as follows:

** So the folowing code is in the user control **

VScrollBar m_verticalScrollBar = new VScrollBar();
Controls.Add(m_verticalScrollBar);

And on the resize event of my control I have

m_verticalScrollBar.Bounds = new Rectangle(Width - SystemInformation.VerticalScrollBarWidth, 0, SystemInformation.VerticalScrollBarWidth, Height);

Ok, it works. The scroll bar is "pinned" to the right hand side BUT as I resize the form I can see the scroll bar being positioned well after the rest of the control has redrawn - it's position is "laggy". If I reduce the width of the form the scroll bar can be seen to be "overtaken" by the right hand edge of the form briefly until it redraws in the correct position. The delay is small but annoying.

Can anyone make any suggestions as to how to get the scroll bar to be "in-sync" with the forms\controls size? (I don't want to have to be drawing a scroll bar from scratch on my graphics surface).

Thanks, Mitch.

Thanks for your responses, So I've simplified the Paint method to the following:

private void MyUserControl(object sender, PaintEventArgs e)
{
      e.Graphics.Clear(BackColor);
      Draw(e.Graphics);  // Draw my stuff
}

I've added:

DoubleBuffered = true;

On the load event, (also tried SetStyle(ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.SupportsTransparentBackColor, true);)

I've removed the resizing of the scroll bar on the controls resize event. Now I just set:

m_verticalScrollBar.Dock = DockStyle.Right;

Still the scroll bar behaves the same on resizing of the user control. Thanks for any further suggestions.

(I appreciate I'm drawing the scroll bar over some of the user controls area, but I don't think that is my problem here. It is the slightly later drawing of the scroll bar that is the problem.)

user3738290
  • 445
  • 3
  • 16
  • 2
    FYI Don't call GC.Collect() in the _Paint event, use using() {} around the disposable objects. You don't need to create a Graphics context, its given to you in e.Graphics – Alex K. Oct 21 '16 at 13:47
  • I second @AlexK.'s advice about creating a `Graphics` object. If the control is double-buffered, calls on `e.Graphics` will draw to the back buffer; if you use `CreateGraphics`, you bypass this behavior. If you insist on using `CreateGraphics`, at least dispose the `Graphics` object when you're done; otherwise your app has a GDI handle leak. Same goes for the `Bitmap` object. – adv12 Oct 21 '16 at 13:53
  • This is a very nonstandard way to do... just about everything. You're implementing your own double-buffering, your own docking mechanism instead of the [Dock Property](https://msdn.microsoft.com/en-us/library/system.windows.forms.control.dock(v=vs.110).aspx)... read up on the classes you're using before you go any further. – adv12 Oct 21 '16 at 13:54
  • Do you intend to draw anything fancier to the `UserControl` than a big black rectangle? If not, just set the `BackColor` property to `Color.Black`. If you are going to do fancier drawing, consider doing your drawing on a custom control (not a `UserControl`) that you dock into your `UserControl` so that the scrollbar is a sibling, rather than a child, of the control you draw to. That way you don't have a scrollbar covering part of the rendered content of the `UserControl`. – adv12 Oct 21 '16 at 14:00
  • Thanks for all your replies, I've added to the main question. – user3738290 Oct 21 '16 at 14:49
  • Ok, forget my code. Just taking a newly generated WinForm and adding a scrollbar (or button or whatever) and setting it's docked property to 'right' produces the same problem. If you grab say the left hand side of the form and start resizing the scroll bar goes crazy. Can this be prevented at all? – user3738290 Oct 21 '16 at 15:13
  • Just use the built-in scrollbar that every window has, set the form's AutoScrollMinSize property. If you are doing this because this is a touch-screen interface and you need a wider scrollbar then just change the system setting. Also [read this](http://stackoverflow.com/a/2613272/17034). – Hans Passant Oct 21 '16 at 15:25
  • Thanks again for all your help. I hadn't really noticed before but it happens on every app I try to a greater or lesser extent - Firefox, Outlook anything. I've simply become aware of it whist developing - I used not to notice and so I should learn to ignore it. Anyway, you've all helped me improve my drawing code. – user3738290 Oct 21 '16 at 15:37

0 Answers0