C#触发事件后使用int值

C#触发事件后使用int值,c#,events,controls,C#,Events,Controls,我一次又一次地问同一个问题。我需要在按钮事件、双击或任何操作之后使用用户输入的值。当我使用设计器时,它会自动将txt控件及其值传递给整个程序,我可以在任何地方使用它。但从程序上来说,我无法解决它。 这里有一个小例子: private void Form1_Load(object sender, EventArgs e) { string blabla = "anything"; Button btn = new Button();

我一次又一次地问同一个问题。我需要在按钮事件、双击或任何操作之后使用用户输入的值。当我使用设计器时,它会自动将txt控件及其值传递给整个程序,我可以在任何地方使用它。但从程序上来说,我无法解决它。 这里有一个小例子:

        private void Form1_Load(object sender, EventArgs e)
    {
        string blabla = "anything";

        Button btn = new Button();
        btn.Location = new Point(10, 40);
        btn.Text = "Click me";
        btn.Click += new EventHandler(btn_Click);
        this.Controls.Add(btn);

    }
    void btn_Click(object sender, EventArgs e)
    {
        MessageBox.Show(blabla);
    }
这不起作用,所以我添加了一个“public”,脚本如下:

    public string blabla;
    private void Form1_Load(object sender, EventArgs e)
    {
        blabla = "anything";

        Button btn = new Button();
        btn.Location = new Point(10, 40);
        btn.Text = "Click me";
        btn.Click += new EventHandler(btn_Click);
        this.Controls.Add(btn);

    }
    void btn_Click(object sender, EventArgs e)
    {
        MessageBox.Show(blabla);
    }
所以我可以用我的变量来改变值。这也适用于控件。 这是可行的,但这会在更大的应用程序中产生数千个公共变量。我如何通过失去这些公众信息来提高可读性?有没有办法使用“ref”?我在自动“提取方法”上看到了它,我只是不知道,我怎么能在事件中使用它


也许我在这方面走错了方向,如果有快捷方式或其他解决方案,请帮助。

这两个代码片段之间的重要更改不是您将变量公开了,而是您将它从
Form1\u Load
方法中的局部变量更改为实例变量。如果在同一个类中处理它,它仍然可以是私有实例变量

但是,另一种方法是将其保留为局部变量,但使用匿名函数来处理事件:

private void Form1_Load(object sender, EventArgs e)
{
    string blabla = "anything";

    Button btn = new Button();
    btn.Location = new Point(10, 40);
    btn.Text = "Click me";
    btn.Click += (sender, args) => {
        MessageBox.Show(blabla);
        // Other code here, but hopefully not too much...
    };
    this.Controls.Add(btn);
}
(如前所述,为了可读性,您不想让匿名函数太大,但它总是可以调用具有所有适当状态的另一个方法。)

编辑:在使用VS2005时,只使用C#2,因此不能使用lambda表达式。不过,您可以使用匿名方法。代码将是:

private void Form1_Load(object sender, EventArgs e)
{
    string blabla = "anything";

    Button btn = new Button();
    btn.Location = new Point(10, 40);
    btn.Text = "Click me";
    btn.Click += delegate {
        MessageBox.Show(blabla);
        // Other code here, but hopefully not too much...
    };
    this.Controls.Add(btn);
}

这两个代码片段之间的重要变化不是将变量公开,而是将它从
Form1\u Load
方法中的局部变量更改为实例变量。如果在同一个类中处理它,它仍然可以是私有实例变量

但是,另一种方法是将其保留为局部变量,但使用匿名函数来处理事件:

private void Form1_Load(object sender, EventArgs e)
{
    string blabla = "anything";

    Button btn = new Button();
    btn.Location = new Point(10, 40);
    btn.Text = "Click me";
    btn.Click += (sender, args) => {
        MessageBox.Show(blabla);
        // Other code here, but hopefully not too much...
    };
    this.Controls.Add(btn);
}
(如前所述,为了可读性,您不想让匿名函数太大,但它总是可以调用具有所有适当状态的另一个方法。)

编辑:在使用VS2005时,只使用C#2,因此不能使用lambda表达式。不过,您可以使用匿名方法。代码将是:

private void Form1_Load(object sender, EventArgs e)
{
    string blabla = "anything";

    Button btn = new Button();
    btn.Location = new Point(10, 40);
    btn.Text = "Click me";
    btn.Click += delegate {
        MessageBox.Show(blabla);
        // Other code here, but hopefully not too much...
    };
    this.Controls.Add(btn);
}

你可以用lambdas来做

btn.Click += (sender, e) => { MessageBox.Show(blabla); }

你可以用lambdas来做

btn.Click += (sender, e) => { MessageBox.Show(blabla); }

所有winforms控件都有一个
标记
属性,类型为
对象
,如果您愿意,可以使用它来存储您自己的自定义数据。这不是一个特别好的实践,并显示了一些其他体系结构问题,但您可以这样做:

private void Form1_Load(object sender, EventArgs e)
{

    Button btn = new Button();
    btn.Location = new Point(10, 40);
    btn.Text = "Click me";
    btn.Click += new EventHandler(btn_Click);
    btn.Tag = "blahblah";
    this.Controls.Add(btn);

}
void btn_Click(object sender, EventArgs e)
{
    Button btn = (Button)sender;
    MessageBox.Show(btn.Tag.ToString());
}

所有winforms控件都有一个
标记
属性,类型为
对象
,如果您愿意,可以使用它来存储您自己的自定义数据。这不是一个特别好的实践,并显示了一些其他体系结构问题,但您可以这样做:

private void Form1_Load(object sender, EventArgs e)
{

    Button btn = new Button();
    btn.Location = new Point(10, 40);
    btn.Text = "Click me";
    btn.Click += new EventHandler(btn_Click);
    btn.Tag = "blahblah";
    this.Controls.Add(btn);

}
void btn_Click(object sender, EventArgs e)
{
    Button btn = (Button)sender;
    MessageBox.Show(btn.Tag.ToString());
}

你可以这样做,我在Form1_Load方法中创建一个闭包

private void Form1_Load(object sender, EventArgs e)
{
    blabla = "anything";

    Button btn = new Button();
    btn.Location = new Point(10, 40);
    btn.Text = "Click me";
    btn.Click += (s,e) => MessageBox.Show(blabla);
    this.Controls.Add(btn);

}

即使
blabla
超出范围,当您单击按钮时,闭包仍会知道它包含文本“anywhere”。

您可以这样做我在Form1_Load方法中创建闭包

private void Form1_Load(object sender, EventArgs e)
{
    blabla = "anything";

    Button btn = new Button();
    btn.Location = new Point(10, 40);
    btn.Text = "Click me";
    btn.Click += (s,e) => MessageBox.Show(blabla);
    this.Controls.Add(btn);

}

即使
blabla
超出范围,当您单击按钮时,闭包仍会知道它包含文本“anywhere”。

他真的应该在表单加载中将按钮创建为局部变量吗?这不是回练吗?@Jethro:为什么不?如果除了处理事件之外,没有什么需要访问控件,我不明白为什么会有问题。这是有道理的。谢谢,Jethro,你能解释一下吗?我有大量的控件需要根据相关的数据库表、事件、选择等进行编程添加,如果我能使其更具可读性,那就太好了。对不起,我的VS已经标记了btn。单击+=(发送者,e)=>{MessageBox.Show(blablabla);}作为错误。他真的应该在表单加载中创建作为局部变量的按钮吗?这不是回练吗?@Jethro:为什么不?如果除了处理事件之外,没有什么需要访问控件,我不明白为什么会有问题。这是有道理的。谢谢,Jethro,你能解释一下吗?我有大量的控件需要根据相关的数据库表,根据事件、选择等以编程方式添加,如果我能使其更具可读性,那就太好了。对不起,但是我的VS已经将btn.Click+=(sender,e)=>{MessageBox.Show(blabla);}标记为错误。很遗憾他们没有在本机上将其设置为“泛型”winforms控件<代码>标签如果没有演员阵容,可能就不会那么混乱。真遗憾,他们没有在本地制作“通用”winforms控件<代码>标签如果没有施法,可能不会那么混乱。