2

How do you draw a string that is supposed to be on top of everything else? Right now in my panel i have some user controls in Panel1.Controls. So i added this to the Paint method:

Graphics g = Panel1.CreateGraphics();  
g.DrawString("BUSTED", new Font("Arial", 20f), new SolidBrush(Color.Black), new PointF(50, 50));

The problem is that the text is printed behind the user controls, so it can't be seen. (If i change the position of the text out in the open, it's displayed correctly).

Any ideas?

Alistair Evans
  • 36,057
  • 7
  • 42
  • 54
Patrick
  • 1,763
  • 5
  • 18
  • 16

4 Answers4

2

All windows forms controls are HWND based, meaning they each have their own window handle and the z-order/parent-child of the controls determines what clips what. The panel paint event is painting onto the panel control, but the panel controls output is clipped by all it's child controls.

Transparency does not work correctly in windows forms. If you set something to have a transparent background, it will typically wind up having the form background show through, and not it's immediate parents.

I have worked around this in various ways.

  1. Do all the compositing yourself by rendering everything to a bitmap and then displaying that. This only works with static content.
  2. Create a windowless rendering model that renders everything like in #1, also handles mouse interaction with its constituent elements.
  3. Create a new top level, layered window (WS_EX_LAYERED) that overlays the control and renders the desired content. This prohibits interaction with the underlying control unless steps are taken to pass messages through. I believe this is the method Visual Studio 2008 uses for the windows form designer surface.
Michael A. McCloskey
  • 2,391
  • 16
  • 19
1

Try adding panel that is over all your controls then drawing in it. The panel must be set with transparency.

Here's more info : Drawing on top of controls inside a panel (C# WinForms)

Community
  • 1
  • 1
Cédric Guillemette
  • 2,394
  • 1
  • 14
  • 22
  • That won't work pre .NET 3.0, since the only way to make a transparent panel before that was using window styles, and not painting the panel, basically. – Alistair Evans Jul 29 '09 at 12:16
  • I tried creating a transparent panel: public class TransparentPanel : Panel { public TransparentPanel() { } protected override CreateParams CreateParams { get { CreateParams createParams = base.CreateParams; createParams.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT return createParams; } } protected override void OnPaintBackground(PaintEventArgs e) { } } But everything is just blurry when i apply it. – Patrick Jul 29 '09 at 12:31
  • I tried this: (This is inside the Paint method of pnlCards (Panel)) TransparentPanel mPanel = new TransparentPanel(); mPanel.Left = pnlCards.Left; mPanel.Top = pnlCards.Top; mPanel.Width = pnlCards.Width; mPanel.Height = pnlCards.Height; g = mPanel.CreateGraphics(); g.DrawString("BUSTED", new Font("Arial", 20f), new SolidBrush(Color.Black), new PointF(50, 50)); this.Controls.Add(mPanel); and i got this result: http://www.pafo.net/error.jpg i want something like: http://www.pafo.net/correct.jpg – Patrick Jul 29 '09 at 13:20
1

Im not sure it will work, but you could try SendToBack on all user controls inside the panel, then maybe the text will show on top.

SwDevMan81
  • 48,814
  • 22
  • 151
  • 184
0

what about overriding OnPaint in Panel, and writing your drawing code AFTER the base paint?

class DrawingPanel : Panel {
    protected override void OnPaint(PaintEventArgs e)
    {
       base.OnPaint(e);

       // Your drawing code here


    }
}
nothrow
  • 15,882
  • 9
  • 57
  • 104