为何我的程序无法在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方法内创建变量则无法使用,恳请提供帮助。
问题分析与解决
你的核心问题是变量作用域错误:在方法内部定义的变量,每次调用方法都会被重新初始化,导致之前点击的坐标数据被清空。必须把存储坐标的数组、计数变量定义为类的成员变量,这样它们的生命周期和窗体一致,能持续保留每次点击的数据。
修改步骤
- 将
Point[] punten、int kliks移到类的成员位置(所有方法外面),初始化时把数组长度设为10(对应你需要的10次点击)。 - 在
MouseClick方法中不再重新定义这些变量,直接使用成员变量。 - 每次点击后计数递增,当收集到至少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
相关产品推荐
相关产品推荐

