你怎么弄清楚是否在c#中点击了任何按钮?

时间:2012-09-30 08:29:56

标签: c# winforms

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

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();
}

有更优雅的方法吗?

6 个答案:

答案 0 :(得分: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,以便一切都清楚。

这是一项微不足道的练习,考虑到你在tic-tac-toe游戏中最多只能有9个按钮。

答案 1 :(得分: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事件中初始化词典

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()
{ ... }

答案 2 :(得分:1)

在Asp.Net中,您可以使用Page_Load及其在Winforms

中的等效内容执行此操作
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();

}

答案 3 :(得分: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 / groupbox是最佳选择,因为有一个属性panel.Controls.OfType<Button>().ForEach(可用于检索面板或任何容器控件中的所有按钮,以最小化代码和编写干净的逻辑。此外,您不需要任何集合

答案 4 :(得分: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;
        }
}

答案 5 :(得分:0)

在C#中,独立使用ASP.NET,WPF,Areo或WinForm。您使用Eventdelegates。要掌握这一点,您应该阅读tutorial about delegatestutorial about events

该示例将基于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);
  }

}

最后一步是将事件分配给按钮,这由重载的operator + =

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

就是这样。