你有兩個問題與圖形對象:
收集在你的當前行的點在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
幾乎總是錯的,並會盡快爲你去超越單一的非持久性繪圖操作很疼..
![enter image description here](https://i.stack.imgur.com/QDkyc.png)
下面是完整的代碼:
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