[英]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控件仅显示在其顶部。
我想到了三种可能的解决方案,这里没有按特定顺序列出:
每当您希望蓝色矩形(或在Panel控件的背景上绘制的任何内容都可见)时,请将WebBrowser控件的Visible
属性设置为false
。 再次将WebBrowser.Visible设置为true
,以便可以使用WebBrowser控件。
而不是将WebBrowser控件添加为Panel的子控件(后者又是容器窗体的子控件),而是将Panel和WebBrowser控件都添加为容器窗体的子控件。 换句话说,扁平化层次结构。 因为这消除了父子关系,所以您现在可以更改控件的Z顺序,从而更改可见的控件。 在WinForms中,使用SendToBack
和BringToFront
成员函数很简单。
创建一个新控件,该控件的名称类似于BlueRectangle
或DrawingSurface
或其他名称,该控件继承自System.Windows.Forms.Control
。 覆盖其OnPaint
事件,并将您的绘图代码放在此处。 将此控件类的实例作为子级添加到Panel控件中。 实际上,您的Panel控件将具有两个子控件: BlueRectangle
控件和WebBrowser
控件。 如上所述,通过使用SendToBack
和BringToFront
更改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.