2013-07-19 36 views
15

我刚刚开始编程,我想使用WinForms制作多个按钮,您可以点击它们将它们从白色变成灰绿色,然后再变成白色。我已经这样做了一个按钮:如何让按钮做同样的事情?

private void button1_Click(object sender, EventArgs e) 
    { 
     if (button1.BackColor != Color.Lime) 
     { 
      button1.BackColor = Color.Lime; 
     } 
     else 
     { 
      button1.BackColor = Color.White; 
     } 
    } 

现在我可以复制并粘贴所有的按钮,但我知道这是低效的;如果我使用winforms引用button2上的button1,它只会改变button1的颜色(显然)。

那么,我需要使用助手方法,新类还是别的吗?那将是什么样子?

+13

道具给你的帮助,不想采取简单的出路,剪切和粘贴大量的代码创建按钮事件和属性。你已经在以正确的方式思考事情了。 –

回答

24

有几种方法。有人可能会创建一个不同的按钮调用通用功能:

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

private void ChangeColor(Button button) 
{ 
    if (button.BackColor != Color.Lime) 
     button.BackColor = Color.Lime; 
    else 
     button.BackColor = Color.White; 
} 

然后每个按钮处理程序可以使用相同的函数调用。

如果所有这些按钮总是会做完全相同的事情,那么您可以对它们全部使用一个点击处理函数。在这种情况下,你需要做的是确定哪个按钮调用处理程序(而你目前直接引用button1),以便知道哪一个要更改。传递给处理函数的sender对象实际上是对调用处理函数的表单元素的引用。所有你需要做的是将它转换:

private void button_Click(object sender, EventArgs e) 
{ 
    var button = (Button)sender; 
    if (button.BackColor != Color.Lime) 
     button.BackColor = Color.Lime; 
    else 
     button.BackColor = Color.White; 
} 

所以首先处理程序抓取到调用它的按钮的引用,然后运行该按钮的逻辑。还请注意我是如何使处理函数的名称更通用的。现在,您将转到表单设计器,并将button_Click设置为所有应调用此按钮的按钮的点击处理程序。

+0

这正是我所期待的。谢谢大家的帮助,解释和善意的话。 – user2600871

+0

+1很好的答案;很好解释。 –

5

您可以通过将sender转换为Button来获得引发Click事件的按钮。

然后,您可以将相同的处理程序添加到每个按钮。

+2

这里也有一个隐含的“具有相同方法处理所有按钮事件”。您可以通过选择控件在Visual Studio中选择控件的事件处理程序,然后在属性窗口中选择“事件”并向下滚动,直到找到“单击”。然后在“点击”旁边的下拉框中,您可以选择发生点击事件时要调用的方法 –

8

可能最简单的方法是让每个按钮调用相同的点击处理程序。然后在您的处理程序中使用发件人而不是硬编码Button1。

private void buttons_Click(object sender, EventArgs e) 
    { 
     var theButton = (Button) sender; 
     if (theButton.BackColor != Color.Lime) 
     { 
      theButton.BackColor = Color.Lime; 
     } 
     else 
     { 
      theButton.BackColor = Color.White; 
     } 
    } 
13

你这样做确切你会做任何C#类的方式。您派生自己的类并自定义基类的行为。每个事件都有一个可以覆盖的相应OnXxxx()方法。

添加一个新类到您的项目并粘贴此代码:

using System; 
using System.Windows.Forms; 

class MyButton : Button { 
    protected override void OnClick(EventArgs e) { 
     // Your code here 
     //... 
     base.OnClick(e); 
    } 
} 

变化的OnClick()的代码,做你想做的事情。编译。您现在将在工具箱的顶部拥有自己的按钮控件。并且可以在表单上放置尽可能多的副本。他们都将表现相同,而不必在表单中添加任何代码。

+0

我不明白为什么这是使用常用方法或共享事件处理程序的优越方法。如果这个按钮真的做了一些有趣的事情,那么这种方法就是要用到不同的形式。否则,这似乎是矫枉过正。 – siride

+1

+1它更好,因为它不会消耗'Click'事件,而只是将行为构建到按钮本身中。该解决方案不涉及事件处理程序,并将代码完全放在其所属的位置。无论这是否过分,都是无关紧要的。编写的代码数量基本相同,而且是可重复使用和可维护的解决方案 - 未来的自我永远不会问“我在哪里编码此按钮的行为?”因为,代码显然在* MyButton *类中。使用任何其他解决方案*如果按钮需要在其他地方重复使用,则存在问题*。 –

+0

@retailcoder:不,有过度工程这样的事情。就是这个。今天,请参阅Jeff Atwood的博客:http://www.codinghorror.com/blog/2013/07/rule-of-three.html。不要浪费时间进行工程重复使用,直到您真正需要它,特别是对于这个显而易见的小程序。 – siride

0

我是一个VB的家伙....在VB.Net中,您可以为事件添加多个处理程序,并将多个事件连接到同一个处理程序。

本子钩住了所有点击以为按钮着色。

Private Sub ColorButtons(sender As System.Object, e As System.EventArgs) _ 
Handles Button1.Click, Button2.Click, .. 

我这个做意外,因为我拖/复制控制,使一个新的,新的按钮被添加到原来的事件,所有的时间。

其他Subs可以处理相同的事件来完成其他工作 - 两者都将执行。

不知道如何在C#中做到这一点。

+0

它在C#中没有什么不同。 –

0

真正做到这一点的正确方法是将每个按钮的click事件与您为此编写的函数关联(您希望函数在单击按钮时运行,对吗?),所以添加以下内容(或类似)到代码中的相应部分:

MyButton1.Click += new RoutedEventHandler(buttons_Click); 
MyButton2.Click += new RoutedEventHandler(buttons_Click); 
etc... 

你可以像你一样多的控件关联的事件处理程序。

+0

注意,'RoutedEventHandler'部分是多余的,因为'Click'事件已经指定它,所以'MyButton1.Click + = buttons_Click;'是足够的。 –

0

我最常做之前是这样的:

private void button2_Click(object sender, EventArgs e) 
{ 
    button1.PerformClick(); 
} 

此代码将只是简单地运行的button1_Click下的代码。

但是尽量不要这样做,只是简单地把它放在一个函数/方法中,就像David所建议的一样。

相关问题