C# WinForm跳棋开发:如何识别被点击的棋盘按钮
C# WinForm跳棋按钮点击识别方案
问题描述
开发8*8规格的Windows Forms跳棋游戏时,使用自定义UpgradedButton类生成64个棋盘按钮,存储在二维数组m_GameButtons中,自定义按钮类内部已保存自身在数组中的[x,y]坐标。初始化代码如下:
private UpgradedButton[,] m_GameButtons; for (int i = 0; i < m_GameSize; i++) { for (int j = 0; j < m_GameSize; j++) { m_GameButtons[i, j] = new UpgradedButton(new Point(i,j)); m_GameButtons[i, j].Location = new Point(left, top); m_GameButtons[i, j].Size = m_ButtonSize; left += m_ButtonSize.Width; if ((i % 2 == 0 && j % 2 == 0) || (i % 2 != 0 && j % 2 != 0)) { m_GameButtons[i, j].Enabled = false; } if ((i < (m_GameSize / 2) - 1) && ((i % 2 == 0 && j % 2 != 0) || (i % 2 != 0 && j % 2 == 0))) { m_GameButtons[i, j].Text = "O"; } else if (i > (m_GameSize / 2) && ((i % 2 == 0 && j % 2 != 0) || (i % 2 != 0 && j % 2 == 0))) { m_GameButtons[i, j].Text = "X"; } Controls.Add(m_GameButtons[i, j]); } }
当前问题为点击按钮时无法直接定位触发事件的按钮,遍历全量64个按钮匹配的方案效率偏低,需要更优实现。
实现方案
完全不需要遍历数组,WinForm事件模型本身就自带触发源标识,两种零遍历实现方式如下:
- 利用Click事件的
sender参数直接获取触发按钮
所有WinForm控件的点击事件处理函数都符合EventHandler委托签名,其中第一个参数sender就是实际触发事件的控件实例。你只需要在初始化按钮时给所有按钮绑定同一个点击事件处理函数:
然后实现对应的事件处理方法,直接强转// 在现有初始化循环里,Controls.Add那行之前加这行即可 m_GameButtons[i,j].Click += GameButton_Click;sender为你的自定义按钮类型,就能直接读取你预存在按钮里的坐标信息:private void GameButton_Click(object sender, EventArgs e) { UpgradedButton clickedBtn = sender as UpgradedButton; if (clickedBtn == null) return; // 直接读取存在自定义按钮里的坐标属性,替换成实际的属性名即可 Point coord = clickedBtn.GridPosition; int x = coord.X; int y = coord.Y; // 后续直接编写点击后的游戏逻辑即可 } - 利用控件自带的
Tag属性存储坐标
如果不想暴露自定义按钮的坐标属性,WinForm所有控件都内置了Tag属性,专门用于存储和控件关联的自定义数据。初始化时直接把坐标存入Tag:
点击事件中直接读取m_GameButtons[i,j].Tag = new Point(i,j);Tag强转为坐标类型即可,不需要依赖自定义按钮的内部属性。
补充说明:退一步说,64个元素的数组遍历开销微乎其微,完全不会造成可感知的性能问题,只是从实现逻辑上完全没必要做这层遍历而已。
内容的提问来源于stack exchange,提问作者thatDude
相关产品推荐
相关产品推荐

