首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在C#中的透明面板中绘制一条移动线

在C#中的透明面板中绘制一条移动线
EN

Stack Overflow用户
提问于 2015-02-09 05:45:00
回答 1查看 1.7K关注 0票数 0

在这方面似乎有无数个问题,但我找不到一个能起作用的问题。所以,我想是时候回答问题1000,001了。

我有一个带有PictureBoxPanel的自定义控件。Panel是具有透明背景的PictureBox的子代。这允许我在加载在PictureBox中的任何图像之上进行tp绘图。

绘图部分工作,但擦除部分不工作。如果我使用Invalidate(),我只会得到一串闪烁,而这一行根本就没有显示出来。

如果最终目标不明显,它应该像任何像样的绘图应用程序一样工作,在其中单击一个点,拖动,线移动与鼠标,直到你放手。

代码:

代码语言:javascript
运行
复制
private void drawLine(Point pt) {
    // Erase the last line
    if (m_lastPoints != null) {
        m_graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
        m_graphics.DrawLine(m_transPen, m_lastPoints[0], m_lastPoints[1]);
    }

    // Set the last points
    m_lastPoints = new Point[] { m_mouseStartPoint, pt };

    m_graphics.DrawLine(new Pen(m_color), m_mouseStartPoint, pt);
}

m_transPen被定义为new Pen(Color.FromArgb(0, 0, 0, 0));

其结果是:

现在,如果我把它改为:

代码语言:javascript
运行
复制
m_graphics.DrawLine(Pens.White, m_lastPoints[0], m_lastPoints[1]);

我明白了,这表明了它应该做什么,只是用白线代替,它们应该是透明的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-09 08:05:54

不用抹去那句老台词!只需使Panel失效并绘制新的,最好是在Paint事件中。

但是要想让它工作,Panel 就不能覆盖 PictureBox。一定是内部的 it!将其放在load或构造函数事件中:

代码语言:javascript
运行
复制
yourPanel.Parent  = yourPictureBox;
yourPanel.Size = yourPictureBox.Size; 
yourPanel.Location = Point.Empty;

(我知道你已经说对了,但也许下一个人只看答案;-)

为了避免闪烁,使用double-buffered Panel..:

代码语言:javascript
运行
复制
class DrawPanel : Panel
{
    public DrawPanel()
    {
        DoubleBuffered =  true;
    }
}

..or,更好的是,PictureboxLabel (与Autosize=false一起使用);两者都打开了DoubleBuffered属性,并且支持比Panels更好的绘图。

实际上是,如果您只想在加载的Image之上绘制一些东西,那么甚至不需要单独的Panel。只需使用PictureBox本身就行了!它有三个独立的层:BackgroundImageImageControl surface

下面是绘制光标控制线的最小代码:

代码语言:javascript
运行
复制
pictureBox1.MouseDown += pictureBox1_MouseDown;
pictureBox1.MouseMove += pictureBox1_MouseMove;
pictureBox1.MouseUp   += pictureBox1_MouseUp;
pictureBox1.Paint += pictureBox1_Paint;

// class level
Point mDown   = Point.Empty;
Point mCurrent = Point.Empty;

void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    if (mDown != Point.Empty) e.Graphics.DrawLine(Pens.White, mDown, mCurrent);
}

void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
    mDown = Point.Empty;
}

void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    {
        mCurrent = e.Location;
        pictureBox1.Invalidate();
    }
}

void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    mDown = e.Location;
}

当您释放鼠标按钮时,该行将消失。

要使其永久化,您需要将其两点存储在绘制它们所需的数据列表中,并在Paint事件中处理该列表。

这个列表可能还应该包括颜色,笔的宽度,然后还有一些,所以设计一个类'drawAction‘会有帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28403514

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档