Control.PerformClick()没有做任何事情,我错过了什么
本文关键字:错过了 什么 任何事 PerformClick Control | 更新日期: 2023-09-27 18:18:42
我已经查看了MSDN文档和几个SO答案,所有迹象都表明这是有效的。在这一点上,我想我要么完全误解了预期的内容,要么我错过了我需要的一行代码。
简而言之,我有一个带有按钮的WinForms应用程序,我想要另一个函数在代码中的某个点"单击"该按钮。以下是相关的部分:
//form.Designer.csthis.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()
被调用时,它似乎没有做任何事情。如果我执行未注释的行,它可以正常工作。
是我错过了什么,还是我完全误解了什么?
您的问题是TestClick()
是您的表单构造器。在表单构造函数完成之前,没有控件可以调用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()
将创建所需的结果。
对不起,我已经更新了我的答案来纠正它。我最初认为这是因为你没有在Form.InitializeComponent()之后调用Button.PerformClick()(来自Form.Designer.cs自动生成的代码),但我被纠正了,这仍然不起作用。
似乎在构造函数中没有充分创建表单以允许Button.PerformClick()。我推测这可能是由于Modal消息循环尚未完全创建,但在查看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();
}
}
或者,正如前面的答案所建议的,您可以从表单调用Button.PerformClick()。OnLoad方法。但是,最好直接从两个位置调用应用程序逻辑,而不是在UI中执行按钮单击。
很抱歉最初的答案是错误的。
确保您的表单已经显示:)如果隐藏或未显示,则无法执行单击操作。至少这种方式对我来说是有效的(我显示一个表单一小会儿,执行一个点击,然后立即隐藏它)。
它有效!