首页 > 解决方案 > 计时器滴答事件中的动态按钮单击事件

问题描述

我有一个带有 9 个按钮的网格。在计时器滴答事件中,一个随机按钮被高亮显示。如果单击突出显示的按钮,则会创建一个动态单击事件,并且在单击事件中该按钮被标记为不同的颜色。动态按钮单击事件中的 counterHits 变量应该跟踪被点击的突出显示的按钮。有时尽管它使变量增加不止一倍。我无法弄清楚为什么会这样。有什么帮助吗?

public partial class Form1 : Form
{

    const int buttons = 9;
    int counterHits;
    int counterTicks;    
    int currentIndex;
    int lastIndex;
    bool hit = false;
    Random r;

    Timer timerGameLoop;
    Timer timerUpdateUI;
    public Form1()
    {
        InitializeComponent();

        timerGameLoop = new Timer();
        timerGameLoop.Interval = 1000;
        timerGameLoop.Tick += t_Tick;

        timerUpdateUI = new Timer();
        timerUpdateUI.Interval = 10;
        timerUpdateUI.Tick += timerUpdateUI_Tick;

        r = new Random();

    }

    // set up the grid and start
    private void btnStart_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < buttons; i++)
        {
            var b = new Button();
            b.Size = new Size(100, 100);
            b.Margin = new Padding(0);
            b.BackColor = Color.White;
            flowLayoutPanel.Controls.Add(b);
        }
        timerGameLoop.Start();
        timerUpdateUI.Start();
    }


    // tick event ui update loop
    void timerUpdateUI_Tick(object sender, EventArgs e)
    {
        lblHitCounter.Text = "hits : " + counterHits.ToString();
        lblTickCounter.Text = "ticks : " + counterTicks.ToString();
    }

    // tick event game loop
    void t_Tick(object sender, EventArgs e)
    {
        // reset to white background if not clicked
        if (!hit)
            flowLayoutPanel.Controls[lastIndex].BackColor = Color.White;
        // highlight button to be clicked
        currentIndex = r.Next(buttons);
        lastIndex = currentIndex;
        flowLayoutPanel.Controls[currentIndex].BackColor = Color.Violet;

        // highligted button clicked
        flowLayoutPanel.Controls[currentIndex].Click += b_Click;

        hit = false;
        counterTicks++;
    }


    // highlighted button clicked event
    void b_Click(object sender, EventArgs e)
    {
        var b = (Button)sender;
        b.BackColor = Color.Olive;
        hit = true;
        counterHits++;
        b.Click -= b_Click;
    }

}

标签: c#winformsevents

解决方案


以下行附加b_Click到您的按钮。仅当您按下按钮时,该事件处理程序才会被删除

flowLayoutPanel.Controls[currentIndex].Click += b_Click;

见执行b_Click

    // highlighted button clicked event
    void b_Click(object sender, EventArgs e)
    {
        //Stugg
        b.Click -= b_Click;←Removed Here only if it is pressed
    }

这一行表示某些按钮附加了多个 EventHandler。因此,当您单击按钮时,事件处理程序会多次运行。


推荐阅读