【问题标题】:Dynamic button click event within a timer tick event计时器滴答事件中的动态按钮单击事件
【发布时间】:2019-11-01 05:30:54
【问题描述】:

我有一个包含 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# winforms events


    【解决方案1】:

    以下行将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。因此,当您单击按钮时,事件处理程序会运行多次。

    【讨论】:

    • 谢谢哈桑,但我不太确定如何通过给出的答案解决问题。
    • @GonzoGonschior,在继续之前,我想确认您是否看到将多次点击事件添加到同一个按钮的问题?
    • 是的,现在我可以看到了。我想现在我已经确定了问题所在。如果随机对象在彼此之后生成相同的数字,则会将第二个处理程序添加到同一个按钮对象,因此将有多个侦听器到同一个按钮实例。
    • @GonzoGonschior 这正是发生的事情!
    • 我会有一个后续问题。有什么方法可以检查有多少监听器订阅了动态创建的事件?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    相关资源
    最近更新 更多