首页 > 解决方案 > 如何为按钮单击 C# 创建事件和正确使用事件处理程序

问题描述

我对 C# 还很陌生,我正在尝试在 WinForms 中创建一个 Hangman 游戏,我已经让游戏功能正常工作,但我正在尝试创建一个表单,用户选择一个类别,然后选择要猜的单词来自所选类别。我有一个 HangEventArgs,如下所示:

public class HangEventArgs : EventArgs
{
    public Category WordCategory { get; set; }
}

和一个数据类(我希望将来扩展它以添加更多功能)。

public enum Category
{
    // Categories are stores here
}

public class HangData
{
    public Category WordCategory { get; protected set; }

    public HangData(Category askWhat)
    {
        WordCategory = askWhat;
    }
}

还有一个存储单词的类

public static class WordsToGuess
{
    public static string[] Capitals =
    {
        "London",
        "Paris" // more words here
    }; // more categories here

最后,我为所有类别设置了按钮单击事件,我创建了自己的按钮以不使用默认的 EventArgs。

private void bCategory_Click(object sender, HangEventArgs e)
{
    MainGame mg = new MainGame(new HangData(e.WordCategory));
    mg.ShowDialog();
}

我一直在尝试像这样使用事件处理程序

public event EventHandler<HangEventArgs>(object sender, HangEventArgs e);

但我不确定在我的代码中实现这一点的正确方法。如果我使用

bCapitals.Click += new EventHandler(bCategory_Click);

我得到一个没有重载匹配委托错误,我被困在如何修复它上。我在这里先向您的帮助表示感谢。

标签: c#winformsevent-handlingdelegates

解决方案


像这样创建您的类别按钮:

public class CategoryButton : Button
{
    protected override void OnClick(EventArgs e)
    {
        // Just discard the `e` argument and pass your own argument.
        base.OnClick(new HangEventArgs { WordCategory = Category.Cities });
    }
}

订阅活动:

categoryButton1.Click += CategoryButton1_Click;

像这样使用

private void CategoryButton1_Click(object sender, EventArgs e)
{
    if (e is HangEventArgs hangEventArgs) {
        MessageBox.Show(hangEventArgs.WordCategory.ToString());
    }
}

请注意,点击机制仍然按预期工作。您不需要自己触发事件。


当然,您可以创建自己的活动;但是,它必须具有不同的名称,例如HangClick,您必须自己触发它。

public class CategoryButton : Button
{
    public event EventHandler<HangEventArgs> HangClick;

    protected virtual void OnHangClick(HangEventArgs e)
    {
        HangClick?.Invoke(this, e);
    }

    protected override void OnClick(EventArgs e)
    {
        OnHangClick(new HangEventArgs { WordCategory = Category.Cities });

        // Optionally, if you want to preserve the standard click event behaviour:
        base.OnClick(e);
    }
}

订阅:

categoryButton1.HangClick += CategoryButton1_HangClick;

像这样使用:

private void CategoryButton1_HangClick(object sender, HangEventArgs e)
{
    MessageBox.Show(e.WordCategory.ToString());
}

推荐阅读