【问题标题】:How to trigger a button event for a dynamic button?如何触发动态按钮的按钮事件?
【发布时间】:2019-05-02 13:46:19
【问题描述】:

我有一个扫雷游戏。有一个动态创建的按钮板。我想要做的是打开整个板子(基本上是对每个按钮执行一个点击事件)。

我曾尝试使用 PerformClick 方法,但它不起作用。首先,我使用btn.Click 事件作为btn.Click += new EventHandler(btn_Click),但由于左/右键的使用,我最近将其更改为btn.MouseUp 事件。即使我使用了btn.Click 事件,PerformClick 也不起作用。


        public Form1()
        {
            InitializeComponent();

            GenerateMineSweeper();

            // my try of using PerfomClick
            for (int i = 0; i < this.Controls.Count; ++i)
            {
                if (this.Controls[i] is Button)
                {
                    Button btn = (Button)this.Controls[i];
                    btn.PerformClick();
                }
            }
        }

        private void GenerateMineSweeper()
        {
            // board is 15 x 25
            Point p = new Point(0, 0);
            for (int i = 1; i <= 15; ++i)
            {
                for (int j = 1; j <= 25; ++j)
                {
                    Button btn = new Button();

                    btn.Location = p;
                    btn.Size = new Size(25, 25);
                    btn.BackColor = Color.RoyalBlue;
                    btn.FlatStyle = FlatStyle.Popup;

                    // btn.Click += new EventHandler(btn_Click);
                    btn.MouseUp += (s, e) =>
                    {
                        switch (e.Button)
                        {
                            case MouseButtons.Left:
                                btn_LeftClick(s, e);
                                break;
                            case MouseButtons.Right:
                                btn_RightClick(s, e);
                                break;
                        }
                    };

                    this.Controls.Add(btn);

                    p.X += 25;
                }
                p.Y += 25;
                p.X = 0;
            }
        }

        private void btn_LeftClick(object sender, EventArgs e)
        {
            Button btn = sender as Button;
            // code
        }

        private void btn_RightClick(object sender, EventArgs e)
        {
            // code
        }

附注: 因为我使用的是 MouseUp 事件,我显然想要一个 LeftClick 事件触发器,而不是 RightClick。

编辑:我也尝试这样做:

for (int i = 0; i < this.Controls.Count; ++i)
{
    if (this.Controls[i] is Button)
    {
        Button btn = (Button)this.Controls[i];
        btn.MouseUp += btn_LeftClick;
    }
}

但我得到了StackOverflowException在 mscorlib.dll 中发生了“System.StackOverflowException”类型的未处理异常)。

【问题讨论】:

  • 您尝试使用 PerformClick 的目的是什么?您已将事件处理程序注释掉,我看不到 btn_click 子例程。另外,如果要使用 MouseUp,则需要使用 MouseEventHandler 而不是 EventHandler。这将使您能够访问 e.Button 以确定用于触发事件的鼠标按钮。
  • @CharlesMay 感谢您对 MouseEventHandler 的建议。我说我曾尝试将 PerformClick 与 EventHandler(btn_Click) 一起使用(不使用 MouseUp 事件,但它不起作用。我的主要项目更加发达,我已经达到了如果玩家点击炸弹按钮,然后游戏结束,整个棋盘应该打开(每个按钮都被按下)。我不知道该怎么做,在那个项目中我使用MouseUp事件,因为我需要左右点击事件。

标签: c# button event-handling


【解决方案1】:

这里有一些示例代码,可以让您了解您正在尝试做的每件事

private void Form1_Load(object sender, EventArgs e)
{
    for (int i = 0; i < 5; i++)
    {
        //Let's put 5 buttons on the form
        Button btn = new Button();
        btn.Location = new Point(10, i * 25);
        if (i == 2)
        {
            btn.Name = "Bomb";
        }
        else
        {
            btn.Name = "btn" + i;
        }
        btn.Text = "Closed";
        //Add a Click EventHandler
        btn.Click += new EventHandler(btn_Click);
        //Add a MouseUp MouseEventHandler
        btn.MouseUp += new MouseEventHandler(btn_MouseUp);
        //Add them to the form
        Controls.Add(btn);
    }
}

private void btn_MouseUp(object sender, MouseEventArgs e)
{
    Button b = sender as Button;
    //Show me which button was used when this event was triggered
    //MessageBox.Show(e.Button.ToString() + " Mouse button was used.");

    //Since the Right button on mouseup will not be considered a Click, we can tell it to PerformClick
    if (e.Button == MouseButtons.Right)
    {
        b.PerformClick();
    }
}
private void btn_Click(object sender, EventArgs e)
{
    Button btn = sender as Button;
    if (btn.Name == "Bomb" && gameOver == false)
    {
        gameOver = true;
        btn.Text = "Boom";
        ExplodeAll(btn);
    }
    else
    {
        btn.Text = "Opened";
    }
}

bool gameOver = false;
private void ExplodeAll(Button sender)
{
    foreach (Button b in this.Controls.OfType<Button>())
    {
        if (b.Name.StartsWith("btn"))
        {
            b.PerformClick();
        }
    }
}

编辑:添加了一个ExplodeAll 方法,该方法可以在单击炸弹时打开所有按钮。点击第三个按钮将模拟炸弹打开所有带有.PerformClick()的按钮

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-28
    • 2010-12-19
    • 2015-10-04
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    相关资源
    最近更新 更多