0

我正在尝试制作井字游戏程序,并想知道如何确定是否单击了任何按钮以及它是哪个按钮。我目前正在重复每个按钮内的代码:

private void button1_Click(object sender, EventArgs e)
{
  button1.Visible = false;
  label1.Text = "X";
  Application.DoEvents();

}
private void button2_Click(object sender, EventArgs e)
{
  button2.Visible = false;
  label2.Text = "X";
  Application.DoEvents();
}

private void button3_Click(object sender, EventArgs e)
{
   button3.Visible = false;
   label3.Text = "X"
   Application.DoEvents();
}

有没有更优雅的方法来做到这一点?

4

6 回答 6

3

有两种方法可以完成您所追求的(假设 WinForms)..

首先,您可以连接所有按钮以指向同一个事件处理程序.. 并检查其名称:

// In the form designer code:
this.buttonNW.Click += new System.EventHandler(this.button_Click);
this.buttonN.Click += new System.EventHandler(this.button_Click);
this.buttonNE.Click += new System.EventHandler(this.button_Click);


// in the form code:
private void button_Click(object sender, EventArgs e) {
    Button thisButton = (Button)sender;

    switch (thisButton.Name) {
        case "buttonNW":
            MessageBox.Show("North West button clicked");
            break;
        case "buttonN":
            MessageBox.Show("Northern button clicked");
            break;
        case "buttonNE":
            MessageBox.Show("North East button clicked");
            break;
    }
}

其次,您可以将逻辑放入它自己的函数中,并为每个单独的事件处理程序调用该函数:

private void buttonNW_Click(object sender, EventArgs e) {
    handleButtonClick("buttonNW");
}

private void buttonN_Click(object sender, EventArgs e) {
    handleButtonClick("buttonN");
}

private void buttonNE_Click(object sender, EventArgs e) {
    handleButtonClick("buttonNE");
}

private void handleButtonClick(string buttonName) {
    switch (buttonName) {
        case "buttonNW":
            MessageBox.Show("North West button clicked");
            break;
        case "buttonN":
            MessageBox.Show("Northern button clicked");
            break;
        case "buttonNE":
            MessageBox.Show("North East button clicked");
            break;
    }
}

我个人会选择选项 2,以便一切都清楚。

不过,考虑到您在井字游戏中最多只能有 9 个按钮,这是一个微不足道的练习。

于 2012-09-30T08:40:29.747 回答
2

处理这种情况的最“优雅”的方法之一是使用字典。这种方法不需要冗长的 switch 语句。

首先使用表单设计器将每个按钮的 Tag 属性设置为唯一的字符串值

button1.Tag = "B1"
button2.Tag = "B2"
button3.Tag = "B3"
button4.Tag = "B4"
....

并将按钮单击事件处理程序设置为相同的方法

button1.Click = "button_click"
button2.Click = "button_click"
button3.Click = "button_click"
button4.Click = "button_click"
....

在代码窗口中,在表单中全局声明一个字典

private Dictionary<string, Action> buttonActions;

在 Form_Load 事件中初始化 Dictionary

buttonActions = new Dictionary<string, Action>();
buttonActions.Add("B1", button1Action);
buttonActions.Add("B2", button2Action);
buttonActions.Add("B3", button3Action);
buttonActions.Add("B4", button4Action);
.....

现在在 button_click 事件处理程序中,您需要编写此代码

private void button_click(object sender, System.EventArgs e)  
{  
    var btnKey = ((Button)sender).Tag.ToString();  
    if(buttonActions.ContainsKey(btnKey))
        buttonActions[btnKey].Invoke();
}

当然,您仍然需要为每个按钮操作编写特定代码,例如

private void button1Action()
{ ... }
private void button2Action()
{ ... }
private void button3Action()
{ ... }
private void button4Action()
{ ... }
于 2012-09-30T08:54:52.020 回答
1

在 Asp.Net 中,您可以从Page_LoadWinforms 中的等效项中执行此操作

button1.Click += new EventHandler(MyButtons_Click);
button2.Click += new EventHandler(MyButtons_Click);
button3.Click += new EventHandler(MyButtons_Click);

protected void MyButtons_Click(object sender, EventArgs e)
{
   Button clickedButton = (Button) sender;

   if(clickedButton.Text == "O")
     doThis();

   if(clickedButton.Text == "X")
      doThat();

}
于 2012-09-30T08:40:52.303 回答
1

我宁愿用它Linq to Object来创建按钮和关联事件以及编写自定义逻辑,因为这个游戏的大部分属性都是相同的。

myFormConstructor()
{    
       //Panel or Container control or collection that is persistant can be used to hold buttons that will be created dynamically i.e. 9 buttons to this panel in our case
       for(int i = 1 ; i <= 9 ; i++)
       {
           var btn = new Button{
                                 Name = "btn"+i.ToString()
                                 Text = i.ToString()
                               });

           btn.Click += new System.EventHandler(listener_button_click);
           pnl.Controls.Add(btn);    
       }
}
///Write common logic for each button using if else
private void listener_button_click(object sender, EventArgs e) 
{

    var btnName = ((Button)sender).Name;
            switch (btnName)
            {
                case "btn1":
                    //handler for btn1 click
                    break;
                case "btn2":
                    //handler for btn2 click
                    break;
            }    
    }

编辑:对于窗口应用程序,使用面板/组框将是最佳选择,因为panel.Controls.OfType<Button>().ForEach(您可以利用一个属性来检索面板中的所有按钮或任何容器控件,以最小化代码并编写干净的逻辑。此外,您不需要任何收藏

于 2012-09-30T09:24:44.797 回答
0

在您的通用单击处理程序方法中,您可以检查调用按钮的名称属性。

private void ButtonClick(object sender, System.EventArgs e)
{
        var btnName = ((Button)sender).Name;
        switch (btnName)
        {
            case "btn1":
                //handler for btn1 click
                break;
            case "btn2":
                //handler for btn2 click
                break;
        }
}
于 2012-09-30T08:42:55.910 回答
0

在 C# 中,独立于您使用 ASP.NET、WPF、Areo 或 WinForm。您使用Eventdelegates。要掌握这一点,您应该阅读有关代表的教程有关事件的教程。

该示例将基于 C# 2.0 和 WinForm。

首先,您必须创建将处理该操作的方法:

private void hadnleActionForButton(Button button) {

   //Do some magic after button press

}

当我们有一个可以发挥魔力的方法时,我们需要创建一个事件并委托使用它,或者我们可以只使用已经存在的事件和委托。

在您的情况下,您希望在单击按钮后执行该操作

所以首先我们创建适合委托的方法:

private void listener_button_click(object sender, EventArgs e) {

  if(sender is Button) {
    Button b = sender as Button;
    handleActionForButton(b);
  }

}

最后一步是将事件分配给按钮,这是通过重载运算符 += 完成的

this.button1.Click += new System.EventHandler(listener_button_click);

就是这样。

于 2012-09-30T08:54:35.397 回答