C# Winform 在 Pancel 上绘制矩形

在C#的WinForms应用程序中,Panel控件本身不直接支持绘图功能,因为它不是一个绘图控件。不过,你可以通过在Panel上覆盖(override)OnPaint方法或者使用Graphics对象来在Panel上绘制图形。下面是如何实现这两种方法的示例:

先添加控件,再设置控件属性

Panel 在 Dock=DockStyle.Fill 的情况下,多个 Panel叠加,透明效果不是WPF那种

方法1:覆盖OnPaint方法

可以通过重写Panel的OnPaint方法来绘制图形。这种方法允许你在每次需要重绘时调用自定义的绘图代码。

namespace VipSoft.ClientForm
{
    public partial class DemoFrm : Form
    {
        public DemoFrm()
        {
            InitializeComponent();
        }

        private void Demo_Load(object sender, EventArgs e)
        {
            ChartControl pnlControl = new ChartControl();
            pnlControl.Dock = DockStyle.Fill;
            pnlControl.Size = new Size(this.Width, this.Height);
            pnlControl.DrawChart();
            pnlDemo.Controls.Add(pnlControl);
        }
    }
}



public partial class ChartControl : UserControl
{
    public ChartControl()
    {
        DrawGrids();
    }
	
     //绘制网格
    private void DrawGrids()
    {
        //先加的控件,显示在最外面
        this.Controls.Add(new Label()
        {
            AutoSize = true,
            Top = 10,
            Left = 20,
            Text = "asdf",
            ForeColor = Color.BlueViolet,
            Font = new System.Drawing.Font("宋体", 36F)
        });


        this.BackColor = Color.Red; 
        Panel pnlGrid = new Panel();
        //pnlGrid.BackColor = Color.Green;
        pnlGrid.Dock = DockStyle.Fill;
        pnlGrid.Paint += new PaintEventHandler(this.CustomPanel_Paint);
        this.Controls.Add(pnlGrid);
    }

    private void CustomPanel_Paint(object sender, PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        // 示例:绘制一个红色的矩形
        g.FillRectangle(Brushes.Blue, 50, 50, 100, 100);
    }
}

image

方法2:使用Graphics对象直接绘制

如果你需要在代码中动态地在Panel上绘制,你可以通过访问Panel的CreateGraphics方法来获取一个Graphics对象,并使用它来绘制。但这种方法通常用于临时绘图或在窗体关闭前绘图,因为它依赖于窗体的当前状态。对于需要频繁重绘的场景,最好使用第一种方法。

private void DrawOnPanel(Panel panel)
{
    using (Graphics g = panel.CreateGraphics())
    {
        // 示例:绘制一个蓝色的椭圆
        g.FillEllipse(Brushes.Blue, 25, 25, 150, 100);
    }
}

使用双缓冲减少闪烁

为了减少绘图时的闪烁问题,你可以使用双缓冲技术。这可以通过在Panel上重写OnPaint方法时设置一个局部的位图缓冲区来实现。

private Bitmap offscreenBitmap; // 用于双缓冲的位图
private void CustomPanel_Paint(object sender, PaintEventArgs e)
{
    if (offscreenBitmap == null) // 初始化位图缓冲区
    {
        offscreenBitmap = new Bitmap(this.Width, this.Height);
    }
    using (Graphics g = Graphics.FromImage(offscreenBitmap)) // 使用位图创建Graphics对象
    {
        g.Clear(this.BackColor); // 清除背景色
        // 在这里绘制你的图形,例如:
        g.FillRectangle(Brushes.Green, 50, 50, 100, 100); // 示例:绘制一个绿色的矩形
    }
    e.Graphics.DrawImage(offscreenBitmap, Point.Empty); // 将位图绘制到控件上
}

image

先画一个背景,再在它的基础上画其它

private void Demo_Load(object sender, EventArgs e)
{
    pnlDemo.Controls.Clear();

    ChartControl  overviewControl = new ChartControl ();
    overviewControl.Dock = DockStyle.Fill;
    overviewControl.DrawChart();
    overviewControl.Size=new Size(this.Width, this.Height);
    pnlDemo.Controls.Add(overviewControl);
}

public partial class ChartControl : UserControl
{

	protected override void OnLoad(EventArgs e)
	{
		DrawGrids();
	}

	//绘制网格
	private void DrawGrids()
	{
	    //先加的控件,显示在最外面
	    this.Controls.Add(new Label()
	    {
	        AutoSize = true,
	        Top = 10,
	        Left = 20,
	        Text = "asdf",
	        ForeColor = Color.BlueViolet,
	        Font = new System.Drawing.Font("宋体", 36F)
	    });


	    //this.BackColor = Color.LightSkyBlue;

	    //作为背景
	    Panel pnlGrid = new Panel();
	    //pnlGrid.BackColor = Color.Green;
	    pnlGrid.Dock = DockStyle.Fill;
	    pnlGrid.Paint += new PaintEventHandler(this.CustomPanel_Paint); 
	    this.Controls.Add(pnlGrid);

	    Panel pnlLine = new Panel();
	    pnlLine.BackColor = Color.Transparent;//将Panel设为透明
	    pnlLine.Dock = DockStyle.Fill;
	    pnlLine.Paint += new PaintEventHandler(this.CustomPanelBitmap_Paint);
	    //pnlLine.Parent = picBox; //将panel父控件设为背景图片控件 
	    pnlGrid.Controls.Add(pnlLine);
	    pnlLine.BringToFront();//将panel放在前面 == 先Add到控件中,再设置,否则无效
	}

	private void CustomPanel_Paint(object sender, PaintEventArgs e)
	{
	    Graphics g = e.Graphics;

	    using (Pen pen = new Pen(Color.Black, 2))
	    {
	        g.DrawLine(pen, 10, 230, this.Width-10, 230); 
	    }
	}

	private Bitmap offscreenBitmap; // 用于双缓冲的位图
	private void CustomPanelBitmap_Paint(object sender, PaintEventArgs e)
	{
	    if (offscreenBitmap == null) // 初始化位图缓冲区
	    {
	        offscreenBitmap = new Bitmap(this.Width, this.Height);
	    }
	    using (Graphics g = Graphics.FromImage(offscreenBitmap)) // 使用位图创建Graphics对象
	    {
	        //g.Clear(this.BackColor); // 清除背景色
	        // 在这里绘制你的图形,例如:
	        g.FillRectangle(Brushes.Yellow, 200, 200, 100, 100); // 示例:绘制一个绿色的矩形
	    }
	    e.Graphics.DrawImage(offscreenBitmap, Point.Empty); // 将位图绘制到控件上
	}

}

image

posted @   VipSoft  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 本地部署 DeepSeek:小白也能轻松搞定!
· 基于DeepSeek R1 满血版大模型的个人知识库,回答都源自对你专属文件的深度学习。
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 在缓慢中沉淀,在挑战中重生!2024个人总结!
· 大人,时代变了! 赶快把自有业务的本地AI“模型”训练起来!
历史上的今天:
2024-01-24 scikit-learn.datasets 机器学习数据集
2024-01-24 Matplotlib.pyplot.scatter 散点图绘制
2023-01-24 Axure 母版与元件
点击右上角即可分享
微信分享提示