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

时间:2015-02-09 05:45:01

标签: c# drawing transparency

在这方面似乎有一百万个问题,但我找不到一个可行的问题。所以,我想这是问题1,000,001的时间。

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

绘图部分有效,但删除部分没有。如果我使用Invalidate(),我只会得到一堆闪烁,而且这条线甚至都没有显示出来。

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

代码:

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

结果:

现在,如果我将其更改为:

m_graphics.DrawLine(Pens.White, m_lastPoints[0], m_lastPoints[1]);

我得到了这个,它显示了它应该做什么,而不是用白线,它们应该是透明的。

1 个答案:

答案 0 :(得分:1)

无需删除旧线!只需使Panel无效并绘制新的,Paint事件中最好。

为此,Panel 不得覆盖 PictureBox。它必须在里面它!把它放在load或constructor事件中:

yourPanel.Parent  = yourPictureBox;
yourPanel.Size = yourPictureBox.Size; 
yourPanel.Location = Point.Empty;

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

要避免闪烁,请使用double-buffered Panel

class DrawPanel : Panel
{
    public DrawPanel()
    {
        DoubleBuffered =  true;
    }
}

实际上,如果您只想在加载的Image之上绘制内容,您甚至不需要单独的Panel。只需借鉴PictureBox本身!它有三个独立的层:BackgroundImageImageControl surface ..

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

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'会帮助..