2015-10-03 33 views
0

我的程序可以使用canvas.Drawline()繪製線條。如何點擊線並更改此顏色(選擇線)?如何在面板上繪製線條並將其選中

private List<Point> coordFirst = new List<Point>(); 
private List<Point> coordLast = new List<Point>(); 
public Graphics canvas; 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      canvas=panel1.CreateGraphics(); 
     } 

存儲在coordFirs中的座標線& coodLast。

+1

你在靶向:的WinForms? WPF? ASP? ...? __Always__相應地標記您的問題! - 如果是WinForrms,這裏有兩個提示:1)__NEVER__嘗試緩存一個Graphics對象! __NEVER__! - 所有繪圖都必須使用'Paint'事件參數的e.Graphics對象! - 2)Winforms中沒有「線條」,只有各種顏色的像素。因此,要選擇一條線,您需要存儲兩個端點的座標,然後確定點擊時是否點擊了它。這可以用數學或通過查看像素來完成。爲獲得更好的建議,我們需要更多關於您的目標的信 – TaW

+1

進行必要的數學見[這裏](https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Line_defined_by_two_points)! - 而不是使用兩個啞列表,你應該定義一個Line類,其中應包含所有信息,比如顏色,寬度,選擇狀態,以及使用Graphics obejct和方法來繪製它們的方法,以查看Point是否在其上! – TaW

回答

5

這裏是一個適合Line類:

class Line 
{ 
    public Color LineColor { get; set; } 
    public float Linewidth { get; set; } 
    public bool Selected { get; set; } 
    public Point Start { get; set; } 
    public Point End { get; set; } 

    public Line(Color c, float w, Point s, Point e) 
    { LineColor = c; Linewidth = w; Start = s; End = e; } 

    public void Draw(Graphics G) 
    { using (Pen pen = new Pen(LineColor, Linewidth)) G.DrawLine(pen, Start, End); } 

    public bool HitTest(Point Pt) 
    { 
     // test if we fall outside of the bounding box: 
     if ((Pt.X < Start.X && Pt.X < End.X) || (Pt.X > Start.X && Pt.X > End.X) || 
      (Pt.Y < Start.Y && Pt.Y < End.Y) || (Pt.Y > Start.Y && Pt.Y > End.Y)) 
      return false; 
     // now we calculate the distance: 
     float dy = End.Y - Start.Y; 
     float dx = End.X - Start.X; 
     float Z = dy * Pt.X - dx * Pt.Y + Start.Y * End.X - Start.X * End.Y; 
     float N = dy * dy + dx * dx; 
     float dist = (float)(Math.Abs(Z)/Math.Sqrt(N)); 
     // done: 
     return dist < Linewidth/2f; 
    } 

} 

定義爲線名單,可能在類級別:

List<Line> lines = new List<Line>(); 

這裏是你如何能與一些初始化行:

for (int i = 0; i < 20; i++) lines.Add(new Line(Color.Black, 4f, 
    new Point(R.Next(panel1.Width), R.Next(panel1.Height)), 
    new Point(R.Next(panel1.Width), R.Next(panel1.Height)))); 

這裏是點擊一個交叉的結果:

panel1.Invalidate(); 

enter image description here

無論何時添加,更改或刪除,你需要做的Panel行通過觸發Paint事件反映新聞

這裏是PanelPaint事件:

private void panel1_Paint(object sender, PaintEventArgs e) 
{ 
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; 
    foreach (Line L in lines) L.Draw(e.Graphics); 
} 

MouseClick事件中,你做了測試:

private void panel1_MouseClick(object sender, MouseEventArgs e) 
{ 
    foreach(Line L in lines) 
      L.LineColor = L.HitTest(e.Location) ? Color.Red : Color.Black; 
    panel1.Invalidate(); 
} 

避免閃爍不使用基本Panel類,因爲它不是doublebuffered。相反,使用一個PictureBoxdoublebuffered Panel子類:

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

注意

  • 沒有所謂的 '行' 中的WinForms,只有各種顏色的像素沒有這樣的事情。因此,選擇一條線需要存儲兩個端點的座標,然後確定點擊時是否點擊了它。

  • 上面的例子顯示瞭如何在數學中做到這一點。

  • 取而代之,可以通過將每條線繪製到位圖上並測試鼠標點擊的像素來測試每條線。但是,繪製這些位圖將不得不在幕後進行數學計算,併爲位圖分配空間,所以數學計算效率會更高。

  • 是的Line類對於這樣一個簡單的事情看起來有點長,但看看現在所有的事件代碼有多短!這是因爲責任是他們所屬的地方!

  • 還要注意在的WinForms做任何繪畫的第一條規則是:決不緩存或存儲Grahics對象。其實你不應該永遠使用CreateGraphics擺在首位,爲Graphics對象將永遠留在範圍和它產生的圖形不會堅持(即生存最小化,最大化序列)..

  • 另外請注意我如何通過e.Graphics對象的Paint事件的參數Line實例,以便他們可以使用當前的Graphics對象繪製自己!

  • 要選擇較細的線,它可以幫助來修改距離檢查一點...

  • 數學運算直接採取形成Wikipedia

+0

謝謝!這解釋了所有和完美的作品 – Kancil

+0

是否有可能更改此代碼以刪除選定的行? – CodexVideos

+1

當然。它在'List '中,所以一旦你找到它,你可以做一個'lines.Remove(foundLine)'。 – TaW

0

你可以改變點擊的所有顏色。通過使用特定對象的點擊事件。

我給你一個按鈕的例子。如果你點擊按鈕,Panal的顏色將會改變。您可以根據您的要求修改代碼。

private List<Point> coordFirst = new List<Point>(); 
    private List<Point> coordLast = new List<Point>(); 
    public Graphics canvas; 



    private void Form1_Load(object sender, EventArgs e) 
    { 
     canvas = panel1.CreateGraphics(); 
    } 





    private void panel1_Click(object sender, EventArgs e) 
    { 
     panel1.BackColor = Color.Blue; 
    } 

    private void nonSelectableButton3_Click(object sender, EventArgs e) 
    { 
     panel1.BackColor = Color.BurlyWood; 
    } 
+0

不是面板背景顏色,而是改變線條的顏色(如果選擇線條) – Kancil

相關問題