繁体   English   中英

如何显示覆盖面板控件中所有内容的矩形?

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

我想在面板控件的所有内容上显示一个矩形图。 到目前为止,面板控件中只有一个WebBrowser。 如果我开始运行程序而没有将WebBrowser添加到面板控件中,那么我将能够看到矩形。 但是,如果我将WebBrowser添加到面板控件中,则它将与我的矩形图重叠。

如何在面板控件的内部创建一个矩形图,该矩形图将覆盖所有内容? (总在最前面)

下面的代码将在面板控件内绘制一个蓝色矩形。 但是它不会显示,因为该面板包含一个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();
        }
    }
}

这是不可能的。 如果将WebBrowser添加为面板的子控件,它将显示面板背景区域的顶部 当然,面板的背景区域是绘制蓝色矩形的位置。 您的图形仍然存在,WebBrowser控件仅显示在其顶部。

我想到了三种可能的解决方案,这里没有按特定顺序列出:

  1. 每当您希望蓝色矩形(或在Panel控件的背景上绘制的任何内容都可见)时,请将WebBrowser控件的Visible属性设置为false 再次将WebBrowser.Visible设置为true ,以便可以使用WebBrowser控件。

  2. 而不是将WebBrowser控件添加为Panel的子控件(后者又是容器窗体的子控件),而是将Panel和WebBrowser控件都添加为容器窗体的子控件。 换句话说,扁平化层次结构。 因为这消除了父子关系,所以您现在可以更改控件的Z顺序,从而更改可见的控件。 在WinForms中,使用SendToBackBringToFront成员函数很简单。

  3. 创建一个控件,该控件的名称类似于BlueRectangleDrawingSurface或其他名称,该控件继承自System.Windows.Forms.Control 覆盖其OnPaint事件,并将您的绘图代码放在此处。 将此控件类的实例作为子级添加到Panel控件中。 实际上,您的Panel控件将具有两个子控件: BlueRectangle控件和WebBrowser控件。 如上所述,通过使用SendToBackBringToFront更改Z顺序在两者之间来回BringToFront

无关紧要的是,您应该首选using语句,以确保自动处置实现IDisposable的对象,而不是显式调用Dispose方法。 例如,这样编写ShowLineJoin方法:

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));
    }
}

更简单,更易读,更安全。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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