如何在 WinForm 中选择形状

问题描述 投票:0回答:1

我有一个 c# WinForm 项目,其中包含以下代码来绘制矩形和椭圆形:

public partial class Form1 : Form
{

    List<Rectangle> _rectangles = new();
    List<Rectangle> _ellipses = new();
    Rectangle _rectInProgress;

    bool DrawingRectangle = false;
    bool DrawingEllipse = false;

    public Form1()
    {
        InitializeComponent();
        DoubleBuffered = true;
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        if (DrawingRectangle || DrawingEllipse)
        {
            _rectInProgress = new Rectangle(e.Location, new Size());
        }
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (MouseButtons == MouseButtons.Left && (DrawingRectangle || DrawingEllipse))
        {
            _rectInProgress.Width = e.Location.X - _rectInProgress.X;
            _rectInProgress.Height = e.Location.Y - _rectInProgress.Y;
            Invalidate();
        }
    }

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        if (DrawingRectangle)
        {
            _rectangles.Add(_rectInProgress);
            Invalidate();
        }
        else if (DrawingEllipse)
        {
            _ellipses.Add(_rectInProgress);
            Invalidate();
        }
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {

        if (_rectangles.Any())
        {
            e.Graphics.DrawRectangles(new Pen(Color.Blue, 3), _rectangles.ToArray());
        }
        if (_ellipses.Any())
        {
            foreach (var ell in _ellipses)
            {
                e.Graphics.DrawEllipse(new Pen(Color.Blue, 3), ell);
            }
        }
        if (MouseButtons == MouseButtons.Left)
        {
            if (DrawingEllipse)
            {
                e.Graphics.DrawEllipse(new Pen(Color.Red, 3), _rectInProgress);
            }
            else if (DrawingRectangle)
            {
                e.Graphics.DrawRectangle(new Pen(Color.Red, 3), _rectInProgress);
            }
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        DrawingRectangle = !DrawingRectangle;
        DrawingEllipse = false;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        DrawingEllipse = !DrawingEllipse;
        DrawingRectangle = false;
    }
}

下一步是使形状可选择,以便可以调整它们的大小。我对这种事情很陌生,所以我不知道从哪里开始。我在互联网上找到了很多示例,但它们都有一个共同点:它们检查光标是否在形状内单击。我需要检查光标是否单击了形状(边框)。

有人对如何进行有任何建议吗?预先感谢!

c# winforms drawing shapes
1个回答
0
投票

一种不错的方法是将绘制的矩形或椭圆形的

GraphicsPath
转换为分配给控件的Region。当您执行此操作时,除了图形路径之外,该控件实际上“不存在”。当您单击边框时,与单击控件相同,而当您单击内部时,则不同。

这里有两个可以通过单击边框来调整大小的控件示例,但在这个非常基本的演示中,大小只能从右下角增加或减小。而且,人们可能希望为鼠标单击保持一个计时器,并将其切换到“移动”而不是“调整大小”。不管怎样,这给了你一些可以尝试的东西。


矩形

class RectangleControl : Control { public RectangleControl() { MouseDown += (sender, e) => { _isResizing = true; _mouseDownPosition = e.Location; _mouseDownSize = Size; }; MouseUp += (sender, e) => _isResizing = false; MouseEnter += (sender, e) => Cursor = Cursors.Cross; MouseLeave += (sender, e) => Cursor = Cursors.Default; MouseMove += (sender, e) => { if (_isResizing && e.Button == MouseButtons.Left) { int deltaX = e.Location.X - _mouseDownPosition.X; int deltaY = e.Location.Y - _mouseDownPosition.Y; var newSize = new Size( _mouseDownSize.Width + deltaX, _mouseDownSize.Height + deltaY); Size = newSize; } }; SizeChanged += (sender, e) => { GraphicsPath path = new GraphicsPath(); path.AddRectangle(new Rectangle(0, 0, Width, Height)); Region region = new Region(path); Rectangle inflatedRect = new Rectangle( BorderWidth, BorderWidth, Width - (BorderWidth * 2), Height - (BorderWidth * 2)); region.Exclude(inflatedRect); Region = region; }; } private Point _mouseDownPosition; private Size _mouseDownSize; bool _isResizing = default; public int BorderWidth { get; set; } = 4; }


椭圆

class EllipseControl : Control { public EllipseControl() { MouseDown += (sender, e) => { _isResizing = true; _mouseDownPosition = e.Location; _mouseDownSize = Size; }; MouseUp += (sender, e) => _isResizing = false; MouseEnter += (sender, e) => Cursor = Cursors.Cross; MouseLeave += (sender, e) => Cursor = Cursors.Default; MouseMove += (sender, e) => { if (_isResizing && e.Button == MouseButtons.Left) { int deltaX = e.Location.X - _mouseDownPosition.X; int deltaY = e.Location.Y - _mouseDownPosition.Y; var newSize = new Size( _mouseDownSize.Width + deltaX, _mouseDownSize.Height + deltaY); Size = newSize; } }; SizeChanged += (sender, e) => { GraphicsPath path = new GraphicsPath(); path.AddEllipse(new Rectangle(0, 0, Width, Height)); Region region = new Region(path); GraphicsPath innerPath = new GraphicsPath(); innerPath.AddEllipse( BorderWidth, BorderWidth, Width - (BorderWidth * 2), Height - (BorderWidth * 2)); region.Exclude(innerPath); Region = region; }; } private Point _mouseDownPosition; private Size _mouseDownSize; bool _isResizing = default; public float BorderWidth { get; set; } = 4; }


主窗体

public partial class MainForm : Form { Rectangle _rectInProgress; public MainForm() { InitializeComponent(); DoubleBuffered = true; } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (MouseButtons == MouseButtons.Left && _isDrawing) { if(radioButtonRectangle.Checked) { using (var pen = new Pen(Brushes.Red, 4F)) { e.Graphics.DrawRectangle(pen, _rectInProgress); } } else { using (var pen = new Pen(Brushes.Red, 4F)) { e.Graphics.DrawEllipse(pen, _rectInProgress); } } } } protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); _isDrawing = true; _rectInProgress = new Rectangle(e.Location, new Size()); } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (MouseButtons == MouseButtons.Left) { _rectInProgress.Width = e.Location.X - _rectInProgress.X; _rectInProgress.Height = e.Location.Y - _rectInProgress.Y; Invalidate(); } } protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); _isDrawing = false; Invalidate(); Control control; if (radioButtonRectangle.Checked) { control = new RectangleControl { Location = _rectInProgress.Location, Size = _rectInProgress.Size, BackColor = Color.Blue, }; } else { control = new EllipseControl { Location = _rectInProgress.Location, Size = _rectInProgress.Size, BackColor = Color.Green, }; } Controls.Add(control); } bool _isDrawing = false; }

© www.soinside.com 2019 - 2024. All rights reserved.