你有两个问题与图形对象:
收集在你的当前行的点在List<Point> currentPoints
并在MouseUp
的currentList
收集到List<List<Point>> allPointLists
!
,那么你可以在Paint
事件得出两个..
foreach (List<Point> points in allPointLists)
if (points.Count > 1) e.Graphics.DrawLines(Pens.Gold, points.ToArray());
if (currentPoints.Count > 1) e.Graphics.DrawLines(Pens.Gold, currentPoints.ToArray());
注意,它会立即支付做是正确的,即绘制只一个有效的图形对象和总是依赖在Paint
事件上,以确保绘图始终根据需要进行更新!使用control.CreateGraphics
几乎总是错的,并会尽快为你去超越单一的非持久性绘图操作很疼..
下面是完整的代码:
List<Point> currentPoints = new List<Point>();
List<List<Point>> allPointLists = new List<List<Point>>();
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
currentPoints = new List<Point>();
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (currentPoints.Count > 1)
{
allPointLists.Add(currentPoints.ToList());
currentPoints.Clear();
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
currentPoints.Add(e.Location);
Invalidate();
}
}
这里是Paint
事件;请注意,我使用两种不同的Pens
作为当前画出的线条和较旧的线条。另外请注意,您可以使用DrawCurve
,而不是DrawLines
获得更平滑的结果..
另外请注意,我用的是List<T>
要灵活WRT元素的数量,而我将其转换为在Draw
命令数组..
private void Form1_Paint(object sender, PaintEventArgs e)
{
Color c1 = Color.FromArgb(66, 77, 88, 222);
using (Pen pen = new Pen(c1, 50f))
{
pen.MiterLimit = pen.MiterLimit/12;
pen.LineJoin = LineJoin.Round;
pen.StartCap = LineCap.Round;
pen.EndCap = LineCap.Round;
foreach (List<Point> points in allPointLists)
if (points.Count > 1) e.Graphics.DrawLines(pen, points.ToArray());
}
Color c2 = Color.FromArgb(66, 33, 111, 222);
using (Pen pen = new Pen(c2, 50f))
{
pen.MiterLimit = pen.MiterLimit/4;
pen.LineJoin = LineJoin.Round;
pen.StartCap = LineCap.Round;
pen.EndCap = LineCap.Round;
if (currentPoints.Count > 1) e.Graphics.DrawLines(pen, currentPoints.ToArray());
}
}
为了防止闪烁不要忘了打开DoubleBuffered
您Form
;或使用DoubleBuffered Panel
子类或简单地使用PictureBox
!
最后说明:我忽略了简单点击的情况;如果他们都应该画你必须赶上他们,大概在if (points.Count > 1)
检查最好,最好在正确的位置和正确的尺寸做了FillEllipse
..
更新
List<T>
是非常有用我很少使用这些日子。下面是如何利用它来实现一个Clear
和Undo
按钮:在MouseUp
代码
private void buttonClear_Click(object sender, EventArgs e)
{
allPointLists.Clear();
Invalidate();
}
private void buttonUndo_Click(object sender, EventArgs e)
{
allPointLists.Remove(allPointLists.Last());
Invalidate();
}
注意两个小的修正这需要妥善处理currentPoints
列表!结算很明显; ToList()
调用正在制作一个拷贝的数据,所以我们不清除我们刚刚添加到列表List的实例!
不要单独画线!收集它们并使用DrawLines(PL!)来代替!您可能会遇到问题,因为您在Paint事件中没有正确绘制。看,通常避免基本错误并不是无关紧要的, - ) - 同时看看pen.MiterLimit并尽量保持它的宽度的一半左右! – TaW
你有一个例子代码片段吗?我已经将它转换成了DrawLines [Point [] pts = new Point [2] {start,end};''g.DrawLines(Pen1,pts);'并且设置了'MiterLimit = 50;'I仍然得到相同的结果。 –
是的,你需要收集__all__你的观点,而不仅仅是使uip一行的两个!只有在你解决第一个问题后,斜角限制才会起作用。 – TaW