简体   繁体   中英

How can I display a rectangle that overlaps everything in a panel control?

I want to display a rectangle drawing over EVERYTHING inside of a panel control. I only have a WebBrowser in the panel control as of now. If I start run the program WITHOUT adding the WebBrowser to the panel control, then I will be able to see the rectangle. But, if I add the WebBrowser to the panel control, then it will overlap my rectangle drawing.

How can I create a rectangle drawing INSIDE of a panel control, that will overlap everything? (always on top)

The code below will draw a blue rectangle inside of the panel control. But it will not be shown, because the panel contains a WebBrowser.

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Graphics_Overlay
{
    public partial class GraphicsOverlayForm : Form
    {
        public GraphicsOverlayForm()
        {
            InitializeComponent();

            Panel panel = new Panel();
            panel.Dock = DockStyle.Fill;
            panel.Paint += panel_Paint;

            WebBrowser webBrowser = new WebBrowser();
            webBrowser.Dock = DockStyle.Fill;
            webBrowser.Url = new Uri("http://stackoverflow.com/");

            Controls.Add(panel);

            // If I comment out the line below then I will
            // be able to see my blue rectangle.
            panel.Controls.Add(webBrowser);
        }

        private void panel_Paint(object sender, PaintEventArgs e)
        {
            ShowLineJoin(e);
        }

        private void ShowLineJoin(PaintEventArgs e)
        {
            // Create a new pen.
            Pen skyBluePen = new Pen(Brushes.Blue);

            // Set the pen's width.
            skyBluePen.Width = 1;

            // Set the LineJoin property.
            skyBluePen.LineJoin = System.Drawing.Drawing2D.LineJoin.Bevel;

            // Draw a rectangle.
            e.Graphics.DrawRectangle(skyBluePen,
                new Rectangle(0, 0, 200, 200));

            //Dispose of the pen.
            skyBluePen.Dispose();
        }
    }
}

This is not possible. If you add the WebBrowser as a child control of the panel, it will be displayed on top of the Panel's background area. The Panel's background area is, of course, where you are drawing the blue rectangle. Your drawing is still there, the WebBrowser control is just being displayed on top of it.

There are three possible solutions that come to mind, listed here in no particular order:

  1. Set the Visible property of the WebBrowser control to false whenever you want the blue rectangle (or whatever is drawn on the background of the Panel control to be visible). Set WebBrowser.Visible to true again so that the WebBrowser control can be used.

  2. Rather than adding the WebBrowser control as a child control of the Panel, which is in turn a child control of the container form, add both the Panel and WebBrowser control as children of your container form. In other words, flatten the hierarchy. Because this removes the parent-child relationship, you can now alter the Z order of the controls, changing which one is visible. This is trivial in WinForms using the SendToBack and BringToFront member functions.

  3. Create a new control, named something like BlueRectangle or DrawingSurface or whatever, that inherits from System.Windows.Forms.Control . Override its OnPaint event and put your drawing code there. Add an instance of this control class to your Panel control, as a child. Effectively, then, your Panel control will have two children: a BlueRectangle control and a WebBrowser control. Shuffle back and forth between the two by changing the Z order, as described above, with SendToBack and BringToFront .

On an unrelated note, you should prefer the using statement as a way of ensuring that an object implementing IDisposable is automatically disposed, rather than explicitly calling the Dispose method. For example, write your ShowLineJoin method like this:

private void ShowLineJoin(PaintEventArgs e)
{
    // Create a new pen with the specified color and width.
    using (Pen skyBluePen = new Pen(Brushes.Blue, 1))
    {
        // Set the LineJoin property.
        skyBluePen.LineJoin = System.Drawing.Drawing2D.LineJoin.Bevel;

        // Draw a rectangle.
        e.Graphics.DrawRectangle(skyBluePen,
        new Rectangle(0, 0, 200, 200));
    }
}

Simpler, easier to read, and safer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM