为所有按钮创建一个通用的按钮点击事件?

huangapple go评论73阅读模式
英文:

Create a generic button click event for all buttons?

问题

目标: 我希望不再编写64个buttonX_clicked()事件,而是编写一个名为buttonHandler()的单一事件,当任何按钮被点击时都会调用它,并使用按钮的解析位置执行相应操作。

背景: 我正在学习如何在C#中使用.NET Forms,并正在开发一个基本的国际象棋应用程序。我的当前用户界面如上所示,它使用了64个单独的按钮,每个按钮代表一个棋盘位置。目前,我使用一个相对丑陋的循环将所有按钮存储在数组中,然后根据它们的位置为它们分配一个起始值。

附注: 如果唯一的解决方案是编写每个buttonX_clicked()以调用buttonHandler(),那么在Visual Studio中以高效的方式执行此操作也将受到赞赏。

英文:

Goal: Instead of coding 64 buttonX_clicked() events I would like to code a single buttonHandler() that is called when any button is clicked and uses the button's parsed position to take the according action.

为所有按钮创建一个通用的按钮点击事件?

Background: I am learning how to use .NET Forms in C# and am working on a basic chess app. My current UI is shown above, it uses 64 individual buttons with one for each board position. I currently use a relatively ugly loop to store all my buttons in an array and then assign them a starting value according to their position.

Sidenote: If the only solution is to code every buttonX_clicked() to call the buttonHandler() then an effecient way to do that in Visual Studio is also appreciated.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace Chess_Test
{
    public partial class UserControl1 : UserControl
    {
        // pawn , knight, bishop, rook, queen, king
        //   1  ,   2   ,   3   ,   4 ,   5  ,  6
        public int[,] nboard = new int[8, 8] {
            { 4, 2, 3, 5, 6, 3, 2, 4 },
            { 1, 1, 1, 1, 1, 1, 1, 1 },
            { 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0 },
            { 1, 1, 1, 1, 1, 1, 1, 1 },
            { 4, 2, 3, 5, 6, 3, 2, 4 }
        };

        Button[] bboard = new Button[64];

        public UserControl1()
        {
            InitializeComponent();
            int i = 0;
            string init = "4235632411111111000000000000000000000000000000001111111142356324";
            foreach (var button in chessPanel.Controls.OfType<Button>())
            {
                if (!button.Name.Contains("usr"))
                {
                    string parsed = Regex.Replace(button.Name, @"[^\d]+", "").Trim();
                    int num = int.Parse(parsed) - 1;
                    bboard[num] = button;
                    button.Text = init[num].ToString();
                }
            }

        }

        private void UserControl1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

答案1

得分: 1

你可以将按钮的行列信息存储在 button.Tag 属性中作为一个元组,并为每个按钮添加一个单一的 button_Click 处理程序。

在事件中,你可以读取元组并获取位置。

if (!button.Name.Contains("usr"))
{            
    string parsed = Regex.Replace(button.Name, @"[^\d]+", "").Trim();
    int position = int.Parse(parsed) - 1;

     // 如果 % 运算等于 0,则返回列 7,否则位置 - 1
    int col = (position % 8) == 0 ? 7 : (position % 8) - 1;

    // 如果 / 运算等于 8,则返回行 7,否则 num / 8
    int row = (position % 8) == 0 ? (position / 8) - 1 : (position / 8); 

    // 将行列添加到标签中
    button.Tag = new Tuple<int, int>(row, col);
    button.Text = init[position].ToString();

    // 在此处添加处理程序
    button.Click += button_Click; 
}

button_Click 方法中:

private void button_Click(object sender, EventArgs e)
{ 
    // 获取被点击的按钮
    Button button = (Button)sender;

    // 从按钮的 Tag 中读取位置
    Tuple<int, int> position = (Tuple<int, int>)button.Tag;

    // 提取行和列
    int row = position.Item1;
    int col = position.Item2;

    // 从你的数组中通过行/列获取图形
    int figure = nboard[row, col];
   
    // ...        
}
英文:

You can store the row col information of your button in the 'button.Tag' property as a Tuple and add a single 'button_Click' handler to every button.

On the event you read the Tuple and get the position.

{
    if (!button.Name.Contains(&quot;usr&quot;))
    {            
        string parsed = Regex.Replace(button.Name, @&quot;[^\d]+&quot;, &quot;&quot;).Trim();
        int position = int.Parse(parsed) - 1;

         // if % operation = 0, return col 7, otherwise position - 1
        int col = (num % 8) == 0 ? 7 : (num % 8) - 1;

        // if / operation = 8, return row 7, otherwise num / 8
        int row = (num % 8) == 0 ? (num / 8) - 1 : (num / 8); 

        // Add row,col to tag
        button.Tag = new Tuple&lt;int, int&gt;(row, col);
        button.Text = init[position].ToString();

        // Add the handler here
        button.Click += button_Click; 
    }
}      
  
private void button_Click(object sender, EventArgs e)
{ 
    // Get the clicked button
    Button button = (Button)sender;

    // Read the position from the buttons Tag
    Tuple&lt;int, int&gt; position = (Tuple&lt;int, int&gt;)button.Tag;

    // Extract the row and col
    int row = position.Item1;
    int col = position.Item2;

    // get the figure from your array by row / col
    int figure = nboard[row, col];
   
    // ...        

}

huangapple
  • 本文由 发表于 2023年6月13日 04:46:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76460227.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定