如何绘制多个可拖动且可选择的圆?

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

我写了一些代码通过鼠标单击在面板上绘制圆圈,我需要添加一些功能,例如选择并拖动这个圆圈,请帮助我完成我的代码,谢谢

Screenshot of running code

CircleItem 类:

public class CircleItem
    {
        public bool Selected { get; set; }
        public Color CircleColor { get; set; }
        public Point StartPoint { get; set; }
        public int LineWidth { get; set; }
        public String Caption { get; set; }

        public CircleItem(String caption, Color circleColor,Point startPoint,int lineWidth)
        {
            CircleColor = circleColor;
            StartPoint = startPoint;
            LineWidth = lineWidth;
            Caption = caption;
        }
        public void Draw(Graphics G)
        {
            using (var pen = new Pen(Color.DimGray, LineWidth))
            {
                G.FillEllipse(new SolidBrush(CircleColor), StartPoint.X, StartPoint.Y, 25, 25);
                G.DrawEllipse(pen, StartPoint.X, StartPoint.Y, 26, 26);
                G.DrawString(Caption, new Font("Arial", 9), Brushes.Green, StartPoint.X + 6, StartPoint.Y + 6);
            }
        }
        public bool HitTest(Point Pt)
        {

            return true;
        }

主要代码:

public partial class Form1 : Form
    {
        public int circleNumber;
        private Point positionCursor;
        private List<Components.CircleItem> circleItems = new List<CircleItem>();

        public Form1()
        {
            InitializeComponent();
            typeof(Panel).InvokeMember("DoubleBuffered", BindingFlags.SetProperty
            | BindingFlags.Instance | BindingFlags.NonPublic, null,
            picCanvas, new object[] { true });
            picCanvas.Paint += PicCanvas_PaintEventHandler;
        }
        private void PicCanvas_PaintEventHandler(object sender, PaintEventArgs e)
        {
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            foreach (CircleItem cItem in circleItems) cItem.Draw(e.Graphics);
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void picCanvas_MouseDoubleClick(object sender, MouseEventArgs e)
        {

        }

        private void picCanvas_MouseClick(object sender, MouseEventArgs e)
        {
            positionCursor = this.PointToClient(new Point(Cursor.Position.X - 25, Cursor.Position.Y - 25));
            if (e.Button == MouseButtons.Left)
            {
                circleItems.Add(new CircleItem(circleItems.Count.ToString(), Color.White, positionCursor, 4));
            }
            else
            {
                foreach (CircleItem cirTag in circleItems)
                    cirTag.CircleColor = cirTag.HitTest(e.Location) ? Color.Red : Color.White;
            }
            picCanvas.Invalidate();
        }

        private void picCanvas_MouseDown(object sender, MouseEventArgs e)
        {

        }
}

感谢关注:)

我尝试编写一些代码来完成此操作,但没有任何好的结果,需要圆形碰撞例程

c# graphics gdi+
1个回答
0
投票

有几件事你需要做

修复你的命中测试

这应该相当简单,只需计算到圆中心点的距离,然后检查它是否小于半径,或者与半径相同(带有一些公差系数)。

如果您正在移动圆圈,请保持跟踪

这需要一个基本的状态机。您需要跟踪一些“状态”,即选择哪个圆(如果有)、是否按下鼠标按钮,以及从鼠标位置到圆中心的偏移量。

当您将鼠标放在圆圈上时,您应该设置所有这些状态。然后,您需要一个 MouseMove 事件的事件处理程序,在其中检查按钮是否被按下,如果是,则将圆心的位置更新为鼠标位置 + 偏移量。您还需要一个 MouseUp 事件的侦听器,以便在释放按钮时重置状态。

您可以使用

Mouse.LeftButton
属性,而不是自己维护
mouseDown
的标志,但您仍然需要跟踪单击的圆圈(如果有)。

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