You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的程序无法在10次鼠标点击的坐标间绘制线条?

问题描述

我正尝试制作一个通过10次鼠标点击确定坐标并在这些坐标间绘制线条的程序,但无法实现功能。
编辑:我意识到需要定义坐标的x、y值,但仍不清楚具体操作方法。

public Form1()
{
    InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
    Point[] punten = new Point[2];
    int index = 0;
    int kliks = 0;
}

private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
    Point[] punten = new Point[2];
    int index = 0;
    int kliks = 0;
    kliks = kliks + 1;
    index = kliks;
    punten[index] = e.Location;

    if (index < 2)
    {
        punten[index] = e.Location;
    }
    else
    {
        Pen pen = new Pen(Color.Blue);
        Graphics papier = pictureBox1.CreateGraphics();
        papier.DrawLines(pen, punten);
    }
}        

我已经把课本读了10遍,但仍不清楚变量应在哪里初始化,若不在pictureBox1_MouseClick方法内创建变量则无法使用,恳请提供帮助。


问题分析与解决

你的核心问题是变量作用域错误:在方法内部定义的变量,每次调用方法都会被重新初始化,导致之前点击的坐标数据被清空。必须把存储坐标的数组、计数变量定义为类的成员变量,这样它们的生命周期和窗体一致,能持续保留每次点击的数据。

修改步骤

  1. 将Point[] punten、int kliks移到类的成员位置(所有方法外面),初始化时把数组长度设为10(对应你需要的10次点击)。
  2. 在MouseClick方法中不再重新定义这些变量,直接使用成员变量。
  3. 每次点击后计数递增,当收集到至少2个点时绘制线条;收集满10个点后可提示或重置。

修改后的完整代码

public partial class Form1 : Form
{
    // 类成员变量,作用域覆盖整个窗体实例
    private Point[] punten = new Point[10]; // 存储10个点击坐标
    private int kliks = 0; // 记录已点击次数

    public Form1()
    {
        InitializeComponent();
    }

    private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
    {
        if (kliks >= 10)
        {
            MessageBox.Show("已收集10个点,停止接收点击");
            return;
        }

        // 保存当前点击的坐标
        punten[kliks] = e.Location;
        kliks++;

        // 至少有2个点时才绘制线条
        if (kliks >= 2)
        {
            // 临时绘制:清空后重新绘制已收集的点
            using (Pen pen = new Pen(Color.Blue))
            using (Graphics papier = pictureBox1.CreateGraphics())
            {
                papier.Clear(pictureBox1.BackColor);
                papier.DrawLines(pen, punten.Take(kliks).ToArray());
            }
            // 触发Paint事件,保证重绘时线条不消失
            pictureBox1.Invalidate();
        }
    }

    // 解决窗口重绘时线条消失的问题,在Paint事件中重新绘制
    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        if (kliks >= 2)
        {
            using (Pen pen = new Pen(Color.Blue))
            {
                e.Graphics.DrawLines(pen, punten.Take(kliks).ToArray());
            }
        }
    }
}

关键说明

  • 成员变量的作用:定义在类内部、方法外部的变量,会在窗体创建时初始化,直到窗体销毁才释放,能持续保留每次点击的坐标数据。
  • Take(kliks)的作用:数组长度固定为10,但可能还没收集满,因此只取已点击的kliks个点来绘制,避免空坐标干扰。
  • Paint事件优化:直接用CreateGraphics绘制的内容会在窗口最小化、被遮挡后消失,在Paint事件中绘制可以保证每次窗口重绘时线条都会重新显示。

内容的提问来源于stack exchange,提问作者Stefan N

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 06:30:35