【问题标题】:How do I make buttons do the same thing?如何让按钮做同样的事情?
【发布时间】:2013-07-19 06:06:45
【问题描述】:

我刚开始编程,我想使用 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的颜色(显然)。

那么,我是否需要使用辅助方法、新类或其他方法?那会是什么样子?

【问题讨论】:

  • 支持您不想采取简单的方法并剪切和粘贴大量代码。你已经以正确的方式思考问题了。

标签: c# winforms button


【解决方案1】:

有几种方法。一种可能是创建一个不同按钮调用的通用函数:

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 设置为应该调用它的所有按钮的点击处理程序。

【讨论】:

  • 这正是我想要的。谢谢大家的帮助、解释和客气话。
【解决方案2】:

您可以完全以与任何 C# 类相同的方式执行此操作。您派生自己的类并自定义基类行为。每个事件都有一个对应的 OnXxxx() 方法,您可以覆盖它。

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

using System;
using System.Windows.Forms;

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

更改 OnClick() 中的代码以执行您想要执行的操作。编译。现在,您将在工具箱顶部拥有自己的按钮控件。并且可以在表单上放置任意数量的副本。它们的行为都相同,无需在表单中添加任何代码。

【讨论】:

  • 我不明白为什么这是一种优于使用通用方法或共享事件处理程序的方法。如果按钮确实做了一些有趣的事情,并且会以不同的形式使用,那么这种方法正是要走的路。否则,这似乎是矫枉过正。
  • +1 更好,因为它不消耗 Click 事件,而只是将行为构建到按钮本身中。该解决方案不涉及事件处理程序,并将代码准确地放在它所属的位置。这是否矫枉过正无关紧要。编写的代码量基本上是相同的,而且它是一个可重用和可维护的解决方案——未来的自我永远不会问“我在哪里再次编写了这个按钮的行为?”因为,好吧,代码显然在 MyButton 类中。对于任何其他解决方案如果按钮需要在其他地方重复使用,就会出现问题
  • @retailcoder:不,存在过度工程这样的事情。就是这个。请参阅 Jeff Atwood 今天的博客,顺便说一句:codinghorror.com/blog/2013/07/rule-of-three.html。在您真正需要之前,不要浪费时间进行过度设计的重用,尤其是对于这个明显微不足道的程序。
  • 抛开关于过度设计的争论,我真的很喜欢这种方法的优雅。正如另一位评论者所说,它将按钮行为的责任直接放在它所属的按钮对象中。这以更简洁的方式应用了面向对象的原则,我唯一不喜欢的是我没有想到它。任何将逻辑从世界的处理程序和代码隐藏中取出并将其放入对象本身的任何事情都是朝着正确方向迈出的一步。这不是过度设计,而是经过深思熟虑的。
【解决方案3】:

可能最简单的方法是让每个按钮调用相同的单击处理程序。然后在您的处理程序内部使用 Sender 而不是硬编码 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;
        }
    }

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

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

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

    这个子钩子所有的点击来为按钮着色。

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

    我总是不小心这样做,因为我拖动/复制一个控件来创建一个新的控件,然后新按钮被添加到原来的事件中。

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

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

    【讨论】:

    • 在 C# 中没有什么不同。
    【解决方案6】:

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

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

    您可以将任意数量的控件关联到事件处理程序。

    【讨论】:

    • 注意RoutedEventHandler部分是多余的,因为Click事件已经指定了它,所以MyButton1.Click += buttons_Click;就足够了。
    【解决方案7】:

    我以前通常是这样的:

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

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

    但尽量不要这样练习,只需像 David 建议的那样将其放入函数/方法中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多