我已经回顾了MSDN文档以及几个SO答案,并且所有迹象都表明这有效。在这一点上,我想我完全误解了会发生什么,或者我错过了我需要的一行代码。
简而言之,我有一个带有按钮的WinForms应用程序,我想要另一个功能在代码中的某一点“点击”该按钮。这是相关的部分:
// form.Designer.cs
this.btnAddBranch.Click += new System.EventHandler(this.btn_add_Click);
// form.cs
// using statements
public partial class EditClient : Form
{
// ...
public TestClick()
{
//btnAddBranch.PerformClick(); <-- would like to know why this fails ...
btn_add_Click(this, EventArgs.Empty);
}
private void btn_add_Click(object sender, EventArgs e)
{
MessageBox.Show("You clicked it!");
}
}
btnAddBranch.PerformClick()
的注释行是我希望它会相当于它下面的行。但它没有,当TestClick()
被调用时似乎没有做任何事情。如果我执行未注释的行,它可以正常工作。
我错过了什么,还是我完全误解了什么?
答案 0 :(得分:9)
您的问题是TestClick()
是您的表单构造函数。在Form Constructor完成之前,没有控件可以调用PerformClick()
。如果你真的想早点调用代码,那就做以下的事情。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//Do not call methods on controls here, the controls are not yet initialized
}
private void TestClick()
{
btn_add.PerformClick();
}
private void btn_add_Click(object sender, EventArgs e)
{
MessageBox.Show("You Clicked it");
}
private void Form1_Load(object sender, EventArgs e)
{
TestClick();
}
}
在表单构造函数以外的任何位置调用PerformClick()
将创建所需的结果。
答案 1 :(得分:7)
抱歉,我已更新我的答案以更正它。我最初认为这是因为你没有在Form.InitializeComponent()(来自Form.Designer.cs自动生成的代码)之后调用Button.PerformClick(),但我更正了这仍然无效。
似乎在构造函数中没有充分创建Form以允许Button.PerformClick()。我认为这可能是由于Modal消息循环尚未完全创建的事实,但在查看Reflector中的Button.PerformClick代码后,情况似乎并非如此。
PerformClick的代码如下所示:
public void PerformClick()
{
if (base.CanSelect)
{
bool flag;
bool flag2 = base.ValidateActiveControl(out flag);
if (!base.ValidationCancelled && (flag2 || flag))
{
base.ResetFlagsandPaint();
this.OnClick(EventArgs.Empty);
}
}
}
在浏览时,我注意到的第一个失败是CanSelect将返回false,因为控件当前不可见(ShowDialog尚未被调用)。因此,PerformClick将无法执行任何操作。这是通过深入了解CanSelect实现:
internal virtual bool CanSelectCore()
{
if ((this.controlStyle & ControlStyles.Selectable) != ControlStyles.Selectable)
{
return false;
}
for (Control control = this; control != null; control = control.parent)
{
if (!control.Enabled || !control.Visible)
{
return false;
}
}
return true;
}
在调试器中,你可以在构造函数中放置一个断点,看看Button1还不可见(有意义)。
但是,我建议您可以通过将应用程序逻辑与Button的事件处理程序分开来完成构造函数的操作。例如......
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DoSomething();
}
private void DoSomething()
{
// application logic here...
MessageBox.Show("Hello World");
}
private void button1_Click(object sender, EventArgs e)
{
DoSomething();
}
}
或者,如前面的答案所示,您可以从Form.OnLoad方法中调用Button.PerformClick()。但是,最好直接从两个位置调用应用程序逻辑,而不是在UI中执行按钮单击。
抱歉最初的错误答案。希望这有助于解释。
答案 2 :(得分:1)
确保您的表单已显示:) 如果隐藏或未显示,则无法执行单击操作。 至少这样它对我有用(我会在短时间内显示一个表格,点击一下,然后立即隐藏它)。
它有效!