簡體   English   中英

如何在MouseDown / Move c#上繪制矩形

[英]How to draw rectangle on MouseDown/Move c#

當我在左鍵單擊鼠標時拖動我的mousedown時,我不太確定如何繪制矩形(未填充)。

到目前為止我有這個

            private void canevas_MouseDown( object sender , MouseEventArgs e )
            {
                    if( e.Button == MouseButtons.Left )
                    {
                            _topLeft = new Point( e.X , e.Y );
                            _drawing = true;
                    }
            }

            private void canevas_MouseMove( object sender , MouseEventArgs e )
            {
                    if( _drawing )
                    {
                            Rectangle rec = new Rectangle( _topLeft.X , _topLeft.Y , ( e.X - _topLeft.X ) , ( e.Y - _topLeft.Y ) );
                            canevas.CreateGraphics().DrawRectangle( Pens.Black , rec );
                    }
            }

但問題是我不希望所有的矩形出現

一些代碼與Ed的正確答案一致:

    Point startPos;      // mouse-down position
    Point currentPos;    // current mouse position
    bool drawing;        // busy drawing
    List<Rectangle> rectangles = new List<Rectangle>();  // previous rectangles

    private Rectangle getRectangle() {
        return new Rectangle(
            Math.Min(startPos.X, currentPos.X),
            Math.Min(startPos.Y, currentPos.Y),
            Math.Abs(startPos.X - currentPos.X),
            Math.Abs(startPos.Y - currentPos.Y));
    }

    private void canevas_MouseDown(object sender, MouseEventArgs e) {
        currentPos = startPos = e.Location;
        drawing = true;
    }

    private void canevas_MouseMove(object sender, MouseEventArgs e) {
        currentPos = e.Location;
        if (drawing) canevas.Invalidate();
    }

    private void canevas_MouseUp(object sender, MouseEventArgs e) {
        if (drawing) {
            drawing = false;
            var rc = getRectangle();
            if (rc.Width > 0 && rc.Height > 0) rectangles.Add(rc);
            canevas.Invalidate();
        }
    }

    private void canevas_Paint(object sender, PaintEventArgs e) {
        if (rectangles.Count > 0) e.Graphics.DrawRectangles(Pens.Black, rectangles.ToArray());
        if (drawing) e.Graphics.DrawRectangle(Pens.Red, getRectangle());
    }

要獲得打開雙緩沖的'canevas',所以它不會閃爍,使用Project + Add New Item,選擇“Class”並粘貼此代碼:

using System;
using System.Windows.Forms;

class Canvas : Panel {
    public Canvas() {
        this.DoubleBuffered = true;
        this.SetStyle(ControlStyles.ResizeRedraw, true);
    }
}

編譯。 將新控件從工具箱頂部拖到窗體上,替換原始的“canevas”。 相應地更新事件處理程序。

不要調用CreateGraphics。 在MouseDown中,存儲起始位置和一個標志以指示您正在繪制。 在MouseMove中,檢查標志。 如果要繪圖,請相對於起始位置創建矩形並將其存儲(您已經在進行),然后調用Invalidate()。 你的所有繪圖代碼都將在OnPaint()中(canvas.Paint來自類外部,但我可能會為此創建自己的類,以避免亂丟你的表單代碼)。

繪圖應該在您的繪圖處理程序(OnPaint)中完成。 如果你在那之外繪制,你的圖形對象不會被清除(因此多個矩形),當你的窗口收到一個WM_PAINT消息時,你在它上面繪制的任何東西都會被看似奇怪的時間消滅掉。

編輯:既然你遇到了性能問題,可以通過幾種簡單的方法來優化繪畫。 首先,Invalidate可選擇將Rectangle作為其參數,這樣您就不必重新繪制整個控件。 其次,如果你正在使用MouseMove,那么你將會畫出相當多的東西。 使用雙緩沖也會有很大幫助,只需將DoubleBuffered屬性設置為true,或者通過調用控件上的SetStyle將其添加到ControlStyles值。

好吧,現在我有這個,它的工作,但它,它閃爍很多,即使有雙緩沖。

            private void canevas_MouseDown( object sender , MouseEventArgs e )
            {
                    _topLeft = new Point( e.X , e.Y );
                    if( e.Button == MouseButtons.Left )
                    {
                            _topLeft = new Point( e.X , e.Y );
                            _drawing = true;
                    }
            }

            private void canevas_MouseUp( object sender , MouseEventArgs e )
            {
                    _drawing = false;
                    _bottomRight = new Point( e.X , e.Y );
                    int newX = _topLeft.X - (_bottomRight.X - _topLeft.X) / 2;
                    int newY =_topLeft.Y + (_bottomRight.Y - _topLeft.Y) / 2;
                    MouseEventArgs me = new MouseEventArgs( MouseButtons.Left , 1 , newX , newY , 0 );

                    canevas_MouseClick( canevas , me );
            }

            private void canevas_MouseMove( object sender , MouseEventArgs e )
            {
                    if( _drawing )
                    {
                            _bottomRight = new Point( e.X , e.Y );
                            canevas.Invalidate();
                    }
            }

然后在油漆上

            private void canevas_Paint( object sender , PaintEventArgs e )
            {
                     Graphics g = canevas.CreateGraphics();
                     g.DrawImage( _buffer , new Rectangle( 0 , 0 , canevas.Width , canevas.Height ) );
                     g.DrawRectangle( Pens.White , new Rectangle( _topLeft.X , _topLeft.Y , ( _bottomRight.X - _topLeft.X ) , ( _bottomRight.Y - _topLeft.Y ) ) );
            }
    public Form1()
    {
        InitializeComponent();
        // Use the cross "+" cursor
        this.Cursor = System.Windows.Forms.Cursors.Cross;
        // This will reduce flicker (Recommended)
        this.DoubleBuffered = true;
    }

將此代碼添加到您的表單。這可能會減少閃爍!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM