当表单上的两个按钮等同时,实际发生了什么?

时间:2017-06-11 10:49:09

标签: c# winforms

假设表单上有两个按钮,button2 private void button1_Click(object sender, EventArgs e) { MessageBox.Show("button1"); } private void button2_Click(object sender, EventArgs e) { MessageBox.Show("button2"); } ,这些事件与它们相关联

button1 = button2

如果我们使用其他按钮执行button1.Equals(button2),那么它们都应引用与button1.Text相同的组件为真,现在例如button2.Text与{{1}相同}},

但如果我点击button1,它仍会显示“button1”,如果我执行button1.Click += button2_Click,则button1仍会显示“button1”,但button2会显示“button2”两次

button2现在有两个引用,以便事件执行两次吗?但实际上在表单上显示的button1呢?我失去了它的参考?我不明白发生了什么以及与具有像BackgroundWorker这样的事件的一般按钮或表单组件实际上有什么相同。

2 个答案:

答案 0 :(得分:1)

事件处理程序附加到按钮对象。 button1button2只是指向该对象的引用变量(我们称之为obj1obj2)。如果您附加事件处理程序,然后让变量button2指向对象obj1,则事件处理程序仍会附加到obj2

答案 1 :(得分:1)

  

如果我们使用另一个按钮执行button1 = button2,那么它们都应该引用与button1.Equals(button2)相同的组件

如果您将button1分配给button2,则全部取决于您执行作业的位置。如果您在button1点击处理程序中执行分配,则单击button1时会这样:

var clickedButton = (Button)sender;
clickedButton = button2;

然后,即使senderbutton1,并且您为其分配了button2,您也只是分配了button1 引用的副本。引用按值传递。

但是,如果你这样做了:

button1 = button2;

并且在您执行此操作的方法中没有button1,然后button1将与button2具有相同的引用。它将与下面相同:

this.button1 = this.button2;

我整理了一个Fiddle来展示这一切。我也会在这里复制代码,以便它可用。代码中有注释提供解释。

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    private static Form f1 = new Form();
    public static void Main()
    {
        f1.button1.Text = "Button 1";
        f1.button2.Text = "Button 2";
        // The Click method will change the buttons but the change 
        // will only be within the Click method. Not outside.
        f1.button1.Click(f1.button1, EventArgs.Empty);

        // This will still write "Button 1"
        Console.WriteLine(f1.button1.Text);

        // Now if we do the assignment like this
        f1.button1 = f1.button2;
        f1.button1.Click(f1.button1, EventArgs.Empty);

        // this will write "Button 2"
        Console.WriteLine(f1.button1.Text);

        // Now pass as reference
        // We will pass button3 whose text is "Button 3" but it will be assigned
        // to button4, so the output will be "Button 4"
        f1.button3.Text = "Button 3";
        f1.button4.Text = "Button 4";
        button1_Click(ref f1.button3, EventArgs.Empty);
        Console.WriteLine(f1.button3.Text);
    }

    public static void button1_Click(ref Button sender, EventArgs e)
    {
        sender = f1.button4;
    }
}

public class Form
{
    public Button button1 = new Button();
    public Button button2 = new Button();
    public Button button3 = new Button();
    public Button button4 = new Button();
    public Form()
    {
        button1.Click += button1_Click;
        button2.Click += button1_Click;
    }

    public void button1_Click(object sender, EventArgs e)
    {
        var clickedButton = (Button)sender;
        clickedButton = this.button2;
    }
}

public class Button
{
    public EventHandler Click;
    public string Text
    {
        get;
        set;
    }
}