如何在 MouseDown/Move C# 上绘制矩形

发布于 2024-09-29 13:05:41 字数 844 浏览 0 评论 0原文

当我在左键单击鼠标的同时向下拖动鼠标时,我不太确定如何绘制矩形(未填充)。

到目前为止,我已经遇到了这个问题

            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 );
                    }
            }

,但问题是我不希望所有矩形都显示出来

I am not quite sure how to draw a Rectangle (not filled) when I drag my mousedown while left clicking the mouse.

I have this so far

            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 );
                    }
            }

But the problems it that I dont want all the rectangles to show up

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情域 2024-10-06 13:05:44
    public Form1()
    {
        InitializeComponent();
        // Use the cross "+" cursor
        this.Cursor = System.Windows.Forms.Cursors.Cross;
        // This will reduce flicker (Recommended)
        this.DoubleBuffered = true;
    }

将此代码添加到您的表单中。这可能会减少闪烁!

    public Form1()
    {
        InitializeComponent();
        // Use the cross "+" cursor
        this.Cursor = System.Windows.Forms.Cursors.Cross;
        // This will reduce flicker (Recommended)
        this.DoubleBuffered = true;
    }

Add this code to your form .this may reduce flickering!

谢绝鈎搭 2024-10-06 13:05:43

一些代码与埃德的正确答案相匹配:

    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”,因此它的绘画不会闪烁,请使用项目+添加新项目,选择“类”并粘贴此代码:

using System;
using System.Windows.Forms;

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

编译。将新控件从工具箱顶部拖到表单上,替换原来的“canevas”。相应地更新事件处理程序。

Some code to go with Ed's correct answer:

    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());
    }

To get a 'canevas' that has double-buffering turned on, so it painting doesn't flicker, use Project + Add New Item, select "Class" and paste this code:

using System;
using System.Windows.Forms;

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

Compile. Drag the new control from the top of the toolbox onto your form, replacing the original 'canevas'. Update the event handlers accordingly.

后来的我们 2024-10-06 13:05:43

不要调用 CreateGraphics。在 MouseDown 中,存储起始位置和一个标志以指示您正在绘制。在 MouseMove 中,检查标志。如果您正在绘制,请创建相对于起始位置的矩形并存储它(您已经在这样做),然后调用 Invalidate()。您的所有绘图代码都将位于 OnPaint() 中(来自类外部的 canvas.Paint,尽管我可能会为此创建自己的类,以避免这些东西弄乱您的表单代码)。

绘图应该在您的绘图处理程序 (OnPaint) 中完成。如果您在其之外进行绘制,则您的图形对象不会被清除(因此会出现多个矩形),并且当您的窗口收到 WM_PAINT 消息时,您在其上绘制的任何内容都可能/将会在看似奇怪的时间被擦除。

编辑:现在您遇到了性能问题,有一些简单的方法可以稍微优化绘画。首先,Invalidate 可以选择将 Rectangle 作为其参数,这样您就不必重新绘制整个控件。其次,如果您在 MouseMove 上绘图,您将会绘制相当多的内容。使用双缓冲也会有很大帮助,只需将 DoubleBuffered 属性设置为 true 或通过调用控件上的 SetStyle 将其添加到 ControlStyles 值即可。

Don't call CreateGraphics. In MouseDown, store the starting position and a flag to indicate that you are drawing. In MouseMove, check the flag. If you are drawing, create the rectangle relative to the starting position and store it (which you are already doing), and then call Invalidate(). All of your drawing code will be in OnPaint() (canvas.Paint from outside the class, though I would probably create my own class for this to avoid littering your form code with this stuff).

Drawing should be done in your paint handler (OnPaint). If you draw outside of that, your graphics object is not cleared (hence the multiple rectangles) and anything you draw to it can/will be wiped out at seemingly odd times when your window receives a WM_PAINT message.

EDIT: Now that you are having performance problems, there are a couple of simple ways to optimize the painting a bit. First, Invalidate will optionally take a Rectangle as its argument so that you don't have to repaint the entire control. Secondly, if you are drawing on MouseMove you are going to be drawing quite a bit. Using double buffering will help a lot too, just set the DoubleBuffered property to true or add it to the ControlStyles value by calling SetStyle on the control.

阳光下的泡沫是彩色的 2024-10-06 13:05:43

好吧,现在我有了这个,它可以工作,但是,即使有双缓冲,它也会闪烁很多。

            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 ) ) );
            }

Alright now I have this, its working but, it flickers alot, even with double buffering.

            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();
                    }
            }

And then on paint

            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 ) ) );
            }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文