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

如何将二维按钮数组的索引传递给EventHandler?

解决按钮点击时获取棋盘索引的问题

嘿,我来帮你搞定这个问题!你的核心需求是点击棋盘按钮时拿到对应的[i,j]索引,进而操作valueBtn数组,咱们先看看原代码里的几个关键问题,再一步步修正:

原代码的问题点

  • valueBtn作用域错误:你在内部循环里声明了valueBtn,这意味着每次循环都会新建一个独立的6x6数组,循环结束后这些数组都会被销毁,而且每个按钮对应的数组都是单独的,完全没法实现全局的棋盘值存储。
  • 事件绑定位置错误:btn[i,j].Click += btnPress;放在了双层循环外面,这时候循环已经结束,i和j的值都是6(超出了数组的索引范围,因为数组是从0到5),不仅会报错,而且根本没给每个按钮绑定点击事件。
  • 缺少索引关联:没有把按钮和对应的[i,j]索引绑定起来,所以点击时没法知道哪个按钮对应哪个位置。

修改后的完整代码示例

首先,把valueBtn改成类的成员变量,这样整个类的方法都能访问它:

// 在类的顶部声明成员变量
private Button[,] btn;
private int[,] valueBtn;
private int currentI, currentJ; // 用来记录当前点击的按钮索引,供drawValue使用

public void board(object obj, EventArgs ea) {
    int n = 6;
    btn = new Button[n, n];
    valueBtn = new int[n, n]; // 在这里初始化全局的二维数组

    // 初始化valueBtn的值(这里先全部设为0,你可以根据需求修改)
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            valueBtn[i, j] = 0;
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int p = 60 * i + 100;
            int q = 60 * j + 100;
            btn[i, j] = new Button();
            btn[i, j].Location = new Point(p, q);
            btn[i, j].Size = new Size(60, 60);
            // 把[i,j]索引存到按钮的Tag属性里,C#7+支持值元组写法
            btn[i, j].Tag = (i, j);
            // 给每个按钮绑定点击事件
            btn[i, j].Click += btnPress;
            this.Controls.Add(btn[i, j]);
        }
    }
    // 只绑定一次Paint事件,避免多次点击重复绑定
    this.Paint += drawValue;
}

public void btnPress(object sender, EventArgs ea) {
    Button pressedBtn = sender as Button;
    if (pressedBtn != null && pressedBtn.Tag is (int i, int j)) {
        // 拿到点击按钮的[i,j]索引
        currentI = i;
        currentJ = j;
        // 获取对应valueBtn的值
        int currentValue = valueBtn[i, j];
        // 触发Paint事件,调用drawValue绘制
        this.Invalidate();
    }
}

// 示例的drawValue方法,你可以根据需求修改绘制逻辑
public void drawValue(object sender, PaintEventArgs e) {
    // 用currentI和currentJ获取要绘制的值
    int valueToDraw = valueBtn[currentI, currentJ];
    // 示例:在窗体上绘制值,位置可以自己调整
    e.Graphics.DrawString(valueToDraw.ToString(), 
                          new Font("Arial", 12), 
                          Brushes.Black, 
                          new PointF(20, 20));
}

关键修改说明

  1. 成员变量重构:把btn和valueBtn都改成类的成员变量,确保所有方法都能访问到同一个棋盘数组。
  2. Tag存储索引:利用Button的Tag属性存储对应的[i,j]索引,这里用了C#7+的值元组写法,简洁方便;如果你用的是旧版本C#,可以用Tuple<int, int>代替,比如btn[i,j].Tag = Tuple.Create(i, j);,然后在btnPress里解析:var tuple = pressedBtn.Tag as Tuple<int, int>; int i = tuple.Item1; int j = tuple.Item2;。
  3. 修正事件绑定:把Click事件绑定放到内部循环里,确保每个按钮都能触发点击事件。
  4. 优化Paint事件绑定:只在board方法里绑定一次Paint事件,每次点击后调用Invalidate()触发重绘,避免多次绑定导致重复绘制。
  5. 索引解析:在btnPress里通过Tag解析出[i,j],然后就能直接访问valueBtn[i,j]的值了。

这样修改后,你点击任意按钮时,就能准确拿到对应的索引和数组值,然后在drawValue里完成绘制啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 17:02:49