【问题标题】:C# event on dynamic object动态对象上的 C# 事件
【发布时间】:2017-10-06 18:38:31
【问题描述】:

我正在尝试将 EventHandler 挂接到动态创建的对象上。在这个示例中,我使用简单的 windows .Net TabControl 来包含动态对象。为简单起见,我使用 Button 及其 Click 事件。 重点是每个 TabPage 上的按钮点击应该产生不同的输出

public partial class Form1 : Form
{
    int letter = 65;

    private void simpleButton1_Click(object sender, EventArgs e)
    {
        TabPage newPage = new TabPage();

        tabControl1.TabPages.Add(newPage);

        Button btn = new Button();

        newPage.Controls.Add(btn);

        btn.Click += (object s, EventArgs ee) =>
        {
            // Button on FirstPage should produce "Test A"
            // Button on SecondPage should produce "Test B"
            Debug.WriteLine("Test " + (char)letter);
        };

        letter++;
    }
}

但是,无论我在任何页面上单击哪个按钮都会产生最后一页的输出(即 4 个 TabPages,所有按钮单击都会产生“Test D”)。感觉好像引用指针 Button btn 指向每个页面上的所有按钮实例。

我的假设:

Button btn = new Button();

每次执行此行时,指针 btn 不会指向 Button 的新实例吗?从这个意义上说:

btn.Click += (object s, EventArgs ee) =>

btn.Click 应该是新创建的 Button 实例的 EventHandler,对吧?似乎指针 btn 仍然引用 Button 的所有实例。

请在这件事上给我启发。提前谢谢你。

【问题讨论】:

    标签: c# events


    【解决方案1】:

    lambda 表达式正在捕获对类中定义的letter 字段的引用,因此该方法将始终使用其中存储的最新值。

    要在创建按钮时捕获letter 的值,首先创建一个局部变量来复制int 的值,然后在lambda 表达式中捕获该局部变量。

    // Create a copy of the value
    var character = (char)letter;
    
    // Now the lambda will capture the local variable
    btn.Click += (object s, EventArgs ee) =>
    {
        Debug.WriteLine("Test " + character);
    };
    

    for loops 的工作方式相同。

    见:

    【讨论】:

    • 噢,谢谢!我忘了声明局部变量将复制其分配的值。效果很好!
    【解决方案2】:

    一个变量只能保存一个值。

    您有 N 个不同的按钮和 N 个不同的事件处理程序。

    但是,您只有一个 letter 字段,所以它们都做同样的事情。

    相反,您可以在函数内部创建一个局部变量;然后,每个按钮将通过closures 使用自己的变量。

    【讨论】:

    • 你的意思是值类型letter
    • 我明白了,似乎值类型letter 不适合我正在尝试的任务。如何为每个 EventHandler 分配不同的“参数”?我希望 Page1 上的 Button 打印“Test A”,PageN 打印“Test N”。是否需要自定义事件对象,比如添加属性?
    • @Suwandy:与值类型无关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 2013-03-02
    • 2020-10-29
    • 1970-01-01
    • 2013-04-16
    相关资源
    最近更新 更多