2009-07-16 30 views
3

首先,我是一個真正的開始在C#所以請溫柔。想要一個繪製的圓圈跟隨我的鼠標在C#

我想要一個圓形跟隨我的光標。我不想讓任何「小徑」落後。

private void Form1_MouseMove(object sender, MouseEventArgs e) 
{ 

    drawCircle(e.X, e.Y); 

} 

private void drawCircle(int x, int y) 
{ 
    Pen skyBluePen = new Pen(Brushes.DeepSkyBlue); 
    Graphics graphics = CreateGraphics(); 
    graphics.DrawEllipse(
     skyBluePen, x - 150, y - 150, 300, 300); 
    graphics.Dispose(); 
    this.Invalidate(); 
} 

這工作正常,因爲它繪製它,並以每個鼠標移動的鼠標爲中心。但是,「this.Invalidate();」是錯的。它在每次運動之後都會「解開」形狀,所以我只能看到它的一瞥。但是,不包括它會導致每個繪製的圓圈都保留在屏幕上。

我該如何獲得一個圓圈,以「優雅地」跟隨我的鼠標周圍,而不會太過激動,並且不會保留所有過去的圓圈?

回答

14

你可以做這樣的事情:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Paint(object sender, PaintEventArgs e) 
    { 
     Point local = this.PointToClient(Cursor.Position); 
     e.Graphics.DrawEllipse(Pens.Red, local.X-25, local.Y-25, 20, 20); 
    } 

    private void Form1_MouseMove(object sender, MouseEventArgs e) 
    { 
     Invalidate(); 
    } 
} 

基本上,在鼠標移動,無效。 在油漆上畫出你的圓圈。

+2

您可以添加「this.DoubleBuffered = true;」作爲ctor的一部分,它也可能有助於一些閃爍。 – 2009-07-16 20:42:51

+0

這就是我需要的一切嗎?我粘貼了它,它實際上並沒有做任何事情,當我跑,除了調出窗體/窗口... – cksubs 2009-07-16 20:53:40

1

您需要在繪製圓圈之前使表單無效。

我確信有更高效的方式來使用雙緩衝來做到這一點,但是我沒有一個例子來說明我的頭腦。

+0

沒有什麼區別。提供相同的閃爍效果。 – 2009-07-16 20:33:56

1

您通常不希望在繪製處理程序之外執行任何繪圖,因爲無論何時繪製處理程序執行(可以在任何時候),它都會覆蓋您執行的任何操作。

還有一堆的事情,你將不得不考慮,最終(比如當鼠標表單之外會發生什麼,但這應該讓你開始

using System; 
using System.Drawing; 
using System.Windows.Forms; 

class C:Form 
{ 
static void Main(){Application.Run(new C());} 

private Point? _MousePosition = null; 

protected override void OnMouseMove(MouseEventArgs e) { 
_MousePosition = e.Location; 
this.Invalidate(); 
} 

protected override void OnPaint(PaintEventArgs e) { 
if(_MousePosition.HasValue) { 
    using(Pen skyBluePen = new Pen(Brushes.DeepSkyBlue)) { 
    e.Graphics.DrawEllipse(skyBluePen, _MousePosition.Value.X - 150, _MousePosition.Value.Y - 150, 300, 300); 
    } 
} 
} 
}
3

這工作 - 只是測試它...

private int x = 0; 
private int y = 0; 

private void Form1_MouseMove(object sender, MouseEventArgs e) 
{ 
    x = e.X; 
    y = e.Y; 

    this.Invalidate(); 
} 

private void Form1_Paint(object sender, PaintEventArgs e) 
{ 
    Pen skyBluePen = new Pen(Brushes.DeepSkyBlue); 

    e.Graphics.DrawEllipse(skyBluePen, x - 150, y - 150, 300, 300); 

} 
0

畫的東西,變化快,最好的方法是使用被稱爲雙緩衝的概念。這真的很容易做到的自己,你不必依靠雙緩衝標誌自己動手給你完全的自由和控制,

基本上,而不是在窗體本身上繪圖,而是在離屏位圖上執行所有繪圖。只有當你知道某些東西已經改變時(在你的情況下,在鼠標移動事件上),你纔會繪製。只有當您知道必須(在鼠標移動或引發Paint事件後)時才繪製屏幕。

private void DrawScene(Point mouseLocation) 
{ 
    myGraphics.Clear(Color.White) 
    myGraphics.DrawEllipse(skyBluePen, mouseLocation.X - 150, mouseLocation.Y - 150, 300, 300); 
    myDrawingSurface.Refresh(); //myDrawingSurface can be a Form or a PictureBox or whatever you'd like. Normally, you'd only Invalidate areas that have changed 
} 

private void myDrawingSurface_MouseMove(object sender, MouseEventArgs e) 
{ 
    DrawScene(e.Location); 
} 

private void myDrawingSurface_Paint(object sender, PaintEventArgs e) 
{ 
    e.Graphics.DrawImage(myBitmap, 0, 0); //Can't remember the exact signature 
} 

這樣做是簡單地一個圖片的圖片屬性分配給您繪製的圖像,並調用刷新的圖片框的另一種「欺騙」的方式。它會處理你的屏幕上的圖像。不需要Paint處理程序。

注意。您需要聲明一次myBitmap和myGraphics。當繪圖表面更改大小時,必須以適當的大小重新創建位圖。另外,做不是不斷重新宣佈鋼筆和其他圖形對象一遍又一遍。他們應該在程序啓動時聲明一次。並在程序關閉時正確處理它們。

1

嘗試添加以下行表單中的構造函數:

this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
this.SetStyle(ControlStyles.UserPaint, true); 

這將告訴表單只當你告訴它這樣做重繪。它也將提供雙緩衝。祝你好運!