2012-08-05 96 views
0

我擁有GDI +的複雜繪圖代碼,它在用戶控件上繪製類似圖表的內容。 如果用戶在按下控件時單擊,則應顯示一個以短劃線樣式的垂直標記線。用gdi +繪製並刪除線+

現在我尋找一種擴展繪圖代碼而不需要觸及複雜繪圖代碼的方法。

我創建了一個標記類,它附加到用戶控件的鼠標事件。 在事件處理程序中,完成了對(ModifierKeys == Keys.Control)的檢查。

如果用戶握住控制鍵並用鼠標左鍵單擊,則以usercontrol的Graphics對象作爲參數調用標記類的繪製方法。

當前的行爲是,每次點擊一個新的線被繪製,但該線應該被刪除,並應繪製一個新的線。

如何擦除畫線?

我是否必須重新繪製用戶控件的comlete內容?

回答

1

這裏的答案顯然是肯定的。在GDI +中,你只需直接畫上一個位圖緩存,所以如果你想撤銷之前的繪圖操作,你可以做的事情之一(取決於問題和性能的複雜性):

  • 恢復個字節已改變位圖上的緩衝
  • 重新加載圖紙位圖

的先前狀態的簡單的解決辦法是有2位圖(類似的東西,通常被稱爲雙緩衝)。一個當前顯示(並且包含最終狀態)和一個僅用於預覽。預覽之一始終是第一個的副本 - 只需進行當前修改即可。

這個簡單的實施,使基本算法:

  • 開始與兩個位圖(空白但相同的大小),如果用戶繪製一條線始終使位圖的副本[命名爲A和B],
  • A有B和第B得出 - 如果用戶完成後再行做B的副本,在A和再次顯示乙
  • - 顯示乙

所以總是顯示預覽位圖,這僅僅是一個修改位圖原來的一個。

這裏是C#示例性編程代碼(假設所有的事件連接和預覽位圖,B,是圖片框本身(這是剛剛命名pictureBox1這裏):

Bitmap bmp; 
bool isDrawing; 
Point previous; 

void pictureBox1_MouseDown(object sender, MouseEventArgs e) 
{ 
    isDrawing = true; 
    previous = e.Location; 
} 

void pictureBox1_MouseUp(object sender, MouseEventArgs e) 
{ 
    isDrawing = false; 
} 

void pictureBox1_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (isDrawing) 
    { 
     using (Graphics g = Graphics.FromImage(bmp)) 
     { 
      double wf = (double)bmp.Width/(double)pictureBox1.Width; 
      double hf = (double)bmp.Height/(double)pictureBox1.Height; 
      g.ScaleTransform((float)wf, (float)hf); 
      g.DrawLine(Pens.Black, e.Location, previous); 
     } 

     pictureBox1.Refresh(); 
     previous = e.Location; 
    } 
} 

該代碼會做只需按下鼠標左鍵,即可顯示從一個點到另一個點的直線。

2

您無法刪除繪製的線條,因爲無法還原底層圖形。

你可以做什麼或者是:

  • 重繪頂部的整個圖形(不含線)

  • 堆棧第二透明用戶控件,並用它來顯示該行。需要時移除並繪製。