我一次又一次地回答同样的问题。我需要在按钮事件,双击或其他任何操作后使用用户输入的值。当我与设计师一起使用时,它会自动将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 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”?我在自动“提取方法”上看到了它,我只是不知道,我怎么能将它用于事件。
也许我在这方面走错了路,如果有快捷方式或其他解决方案,请帮忙。
答案 0 :(得分:4)
两个片段之间的重要变化不是您将变量设为公开的事实 - 而是您将其从Form1_Load
方法中的 local 变量更改为实例变量。如果你在同一个类中处理它,它仍然可以是一个私有实例变量。
但是,另一种方法是将其保留为局部变量,但使用匿名函数来处理事件:
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);
}
答案 1 :(得分:2)
所有winforms控件都具有Tag
属性,类型为object
,您可以根据需要使用该属性存储自己的自定义数据。它不是特别好的做法,并且显示出一些其他的建筑问题,但是在这里你去了:
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());
}
答案 2 :(得分:0)
你可以用lambdas来做。
btn.Click += (sender, e) => { MessageBox.Show(blabla); }
答案 3 :(得分:0)
你可以在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
超出范围,当您单击按钮时,闭包仍然会知道它包含“任何”文本。