2015-02-09 84 views
0

这里似乎有100万个问题,但我找不到能工作的问题。所以,我想现在是问题1,000,001的时候了。在C#中的透明面板中绘制移动线条

我有一个自定义控件与PictureBoxPanelPanel是具有透明背景的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

无需擦除旧线!只需使Panel无效,然后绘制新的,最好在Paint事件中。

这个工作,Panel不能覆盖PictureBox。它必须是里面的吧!将这个负载或构造事件:

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

+0

如何使用控制面? – David 2015-02-09 21:31:36

+0

__Exactly__像你(应该)使用Panel的表面!两者都是控件,都可以绘制。最好使用“Paint”事件,在Class变量中保留Line的2个点,并在更改时使Picturebox失效。在Paint事件中使用'e.Graphics.DrawLine(..)'! – TaW 2015-02-09 21:41:38

+0

为正确的方式绘制到一个控制看到的例子! – TaW 2015-02-09 22:01:24