2014-04-07 160 views
0

現在我在C#中繪製一些形狀上面板的工作定義矩形MS畫圖用戶。我在更新當前圖形時遇到問題。換句話說,我不知道如何創建一個當前舞臺(我將繪製當前舞臺,比如矩形),然後在Panel上繪製。我可以在Panel的Mouse_down事件上繪製一個矩形。但如何顯示在Mouse_move事件當前矩形,按下面板上後,鼠標???我不想用Invalidate。因爲它清除了之前製作的所有面板圖。幫我表明,當鼠標移動目前的矩形,並繪製它的面板後,才釋放鼠標。借鑑鼠標移動

Pen p_white = new Pen(new SolidBrush(Color.White), pen_thickness); 
int w1 = Math.Abs(starx - curx); int h1 = Math.Abs(stary - cury); 
Rectangle rec_new = new Rectangle(starx, stary - h1, w1, h1); 
gpath.Reset(); 
gpath.AddRectangle(rec_new);// code that adds Rectangle in MOUSE_MOVE EVENT 

g.DrawPath(p, gpath); 
// Drawing the rectangle on Mouse Release Event. g was already binded to Panel.CreateGraphics 
+0

你可以讓你的問題更清楚,,,,你在哪裏要顯示你的繪圖和你在哪裏想得出吧.. – HackerMan

+0

我希望我的矩形面板上繪製的,如MS畫圖,我得到的Mouse_Down事件的起點,然後當我移動鼠標的時候,我的矩形會自動改變它的大小,就像在MS Paint中一樣,然後只有在鼠標被釋放後才能繪製(保存)。 – user3505681

回答

0

使用的Invalidate()調用paint方法。

而且你必須有移動所有繪圖!所以這條線

g.DrawPath(p, gpath); 

進入這樣的Paint事件:

e.Graphics.DrawPath(p, gpath); 

既然你正在建設一個GraphicsPath的,這是一個小的變化。如果像創建更多GraphicsPath一樣構建繪圖,則它們都必須繪製在那裏。

無法通過,就像您在紙上面板上繪製反覆建立的圖。你必須以某種方式存儲繪圖操作。這聽起來很乏味,但在這裏你必須移動一條線。

和:你的進步,它會給你機會無限索馬里發展事務處,脫屑等。

+0

謝謝你,這是有效的,但另一個問題出現了,我畫的矩形縮小了,並改變了它的座標。爲什麼?我知道它發生Invalidata();叫做 – user3505681

+0

它沒有。無效只會使Paint發生。所以你的路徑中的座標現在指的是不同的東西。如果沒有MouseDown,-Up,-Move和Paint的代碼,我們不能說明原因。 – TaW

+0

..但我可以猜測:有些事件可能是指小組,其他人可能是指形式,是的?確保所有參考面板,所以他們的座標意味着相同!每個控件都有一個Paint,一個MouseUp等事件!形式也是如此。 (其中__is__是一個控件) – TaW

0

MSDN請參見本附註:

Windows窗體控件不支持真正的透明。透明Windows窗體控件的背景 由其父 繪製。

不幸的是,這意味着我們不能通過簡單的方式來做到這一點 - 通過將某種透明圖像控件放在另一個控件上。 WinForms不會這樣做。

我用過的一種方法是在'前景'緩衝區內完成所有的臨時圖形(選區,不完整的圖形等),並使用背景圖像控件的Paint事件來根據需要繪製臨時對象。

給定一個包含圖像的PaintBox控件,可以使用Paint事件根據需要繪製前景緩衝區,提供完全透明度選項。

public partial class Form1 : Form 
{ 
    public Bitmap Foreground; 

    public Form1() 
    { 
     InitializeComponent(); 

     // Create foreground buffer same size as picture box 
     Foreground = new Bitmap(pictureBox1.Width, pictureBox1.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); 

     // Draw a blue ellipse in the foreground buffer for something to see 
     using (var g = Graphics.FromImage(Foreground)) 
     { 
      g.Clear(Color.Transparent); 
      g.DrawEllipse(Pens.Blue, 10, 10, 300, 100); 
     } 
    } 

    private void pictureBox1_Paint(object sender, PaintEventArgs e) 
    { 
     e.Graphics.DrawImage(Foreground, 0, 0); 
    } 
} 

假設你的圖片框在它的東西,這將繪製一個橢圓藍在它的頂部。

無論何時您想更改重疊的前景圖像,都需要確保PaintBox控件將被重繪。使用Invalidate方法告訴Windows控件需要重新繪製。

一些更多的代碼:

private void Form1_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.KeyCode == Keys.Enter) 
     { 
      e.SuppressKeyPress = true; 
      e.Handled = true; 

      // draw foreground to background 
      using (var g = Graphics.FromImage(pictureBox1.Image)) 
       g.DrawImage(Foreground, 0, 0); 

      // clear foreground 
      using (var g = Graphics.FromImage(Foreground)) 
       g.Clear(Color.Transparent); 
     } 
     else if (e.KeyCode == Keys.Space) 
     { 
      e.SuppressKeyPress = true; 
      e.Handled = true; 

      // a random number source - probably better at form level 
      var rnd = new Random(); 

      // draw a new random ellipse 
      using (var g = Graphics.FromImage(Foreground)) 
      { 
       g.Clear(Color.Transparent); 
       g.DrawEllipse(Pens.Red, 0, 0, 30 + rnd.Next(500), 30 + rnd.Next(500)); 
      } 

      // tell Windows to redraw the paintBox to show new foreground image 
      pictureBox1.Invalidate(); 
     } 
    } 

EnterPaintBox前景緩衝器到圖像時,按Space生成在前臺緩衝區中的隨機新的紅色橢圓。對於各種東西可以使用相同的基本技術,如將圖像粘貼到特定位置(粘貼到前景緩衝區並在其中移動,然後在完成時將前景複製到背景頂部),顯示選擇對象等。

+0

謝謝,這很有效,但是出現了另一個問題,我繪製的矩形縮小並改變其座標。爲什麼?我知道它發生Invalidata();叫做 – user3505681

+0

這個'pictureBox1_Paint'和這個'Form1_KeyDown'是混合它引用的控件,所以座標意味着不同的東西;要麼在面板事件中發生所有事情,要麼糾正面板的事故! – TaW

+0

@ user3505681如果您正在繪製的圖像以任何方式轉換 - 縮放,翻譯,縮放等 - 您需要在繪圖代碼中執行相同的轉換。我使用了一個PictureBox來保存沒有縮放或其他操作的圖像,在面板內按照需要處理滾動。 – Corey