Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么条件阻止PerformClick工作,但允许InvokeOnClick工作?_C#_Winforms - Fatal编程技术网

C# 什么条件阻止PerformClick工作,但允许InvokeOnClick工作?

C# 什么条件阻止PerformClick工作,但允许InvokeOnClick工作?,c#,winforms,C#,Winforms,我试图调试一个winforms应用程序,其中一个进程中的工作表单已在另一个进程中重用。表单将在指定的等待时间后向用户显示按钮。在最初的过程中,这些按钮工作正常。在第二个过程中,这些按钮不起作用 在研究这一点时,我向后推进,首先确保我可以显式调用事件处理程序(这是有效的),然后尝试调用PerformClick。未使用PerformClick调用事件处理程序。进一步环顾四周,我找到了InvokeOnClick,它确实触发了事件处理程序,因此很明显,在第二个进程中,我需要修复一些阻止访问按钮的条件 我

我试图调试一个winforms应用程序,其中一个进程中的工作表单已在另一个进程中重用。表单将在指定的等待时间后向用户显示按钮。在最初的过程中,这些按钮工作正常。在第二个过程中,这些按钮不起作用

在研究这一点时,我向后推进,首先确保我可以显式调用事件处理程序(这是有效的),然后尝试调用PerformClick。未使用PerformClick调用事件处理程序。进一步环顾四周,我找到了InvokeOnClick,它确实触发了事件处理程序,因此很明显,在第二个进程中,我需要修复一些阻止访问按钮的条件

我找到的唯一一个定义是“PerformClick在引发click事件之前检查按钮是否“可用”,这就是为什么PerformClick不起作用时InvokeOnClick起作用。我在断点处检查了按钮是否可见并已启用,我还应查找哪些其他条件

更新:好吧……回到困惑,对需要检查的东西进行三次打击。确认表单上没有验证事件处理程序,CanSelect返回true。从MSDN:

如果System.Windows.Forms.ControlStyles的可选值设置为true,并且包含在另一个控件中,控件本身可见并已启用,并且其所有父控件可见并已启用,则此属性返回true

据我所知:

  • 按钮及其所有父项必须启用且可见
  • 控件必须是可选择的(
    ControlStyles.selective
  • 必须满足验证规则
除非您手动处理
控件样式
,否则最有可能的情况是,按钮的验证组中存在验证失败的情况(或阻止验证控件更改焦点的情况),或者相关按钮的父项之一被禁用和/或不可见。

据我所知:

  • 按钮及其所有父项必须启用且可见
  • 控件必须是可选择的(
    ControlStyles.selective
  • 必须满足验证规则

除非您手动处理
控件样式
,否则最有可能的情况是,按钮的验证组中存在验证失败的情况(或阻止验证控件更改焦点的情况),或者相关按钮的父项之一被禁用和/或不可见。

要添加到@Luaan,回答,
InvokeOnClick
只调用控件的
OnClick
函数。它不检查任何东西。这是
InvokeOnClick
()

其中,这是
PerformClick
()

CanSelect
的实现方式如下:

if ((controlStyle & ControlStyles.Selectable) != ControlStyles.Selectable) {
  return false;
}
for (Control ctl = this; ctl != null; ctl = ctl.parent) {
  if (!ctl.Enabled || !ctl.Visible) {
     return false;
  }
}

因此,我基本上是在@Luaan的答案中添加内容,这是完全正确的:无需进一步解释(他的解释是100%正确的),我只是在添加证据:-)

要在@Luaan的答案中添加内容,
调用OnClick
只需调用控件的
OnClick
函数。它不检查任何东西。这是
InvokeOnClick
()

其中,这是
PerformClick
()

CanSelect
的实现方式如下:

if ((controlStyle & ControlStyles.Selectable) != ControlStyles.Selectable) {
  return false;
}
for (Control ctl = this; ctl != null; ctl = ctl.parent) {
  if (!ctl.Enabled || !ctl.Visible) {
     return false;
  }
}

因此,我基本上是在@Luaan的答案上添加内容,这是完全正确的:无需进一步解释(他的解释是100%正确的),我只是在添加证据:-)

为了完整性,我正要写基本相同的答案,所以+1:-),我还要补充一点,在您调用
PerformClick
时,代理必须实际添加到按钮的
click
事件中,这听起来太明显了,但可能值得检查是否有什么东西实际删除了它(或在稍后阶段添加了它),谢谢。非常确定我们没有针对这个特定表单的验证规则,所以我进入了所有权和可选状态链,我准备写下基本相同的答案,所以+1:-)为了完整性,我还要补充一点,在您调用
PerformClick
时,代理必须实际添加到按钮的
click
事件中,这听起来太明显了,但可能值得检查是否有什么东西实际删除了它(或在稍后阶段添加了它),谢谢。非常确定我们没有针对这个特定表单的验证规则,所以我进入了所有权和可选状态链,感谢您的证明,以及参考源链接!Winforms对于一个以web应用程序开发为主的开发者来说仍然有点奇怪和困惑。谢谢你的证明和参考源链接!Winforms对于一个以web应用程序开发为主的开发者来说仍然有点奇怪和困惑。
if ((controlStyle & ControlStyles.Selectable) != ControlStyles.Selectable) {
  return false;
}
for (Control ctl = this; ctl != null; ctl = ctl.parent) {
  if (!ctl.Enabled || !ctl.Visible) {
     return false;
  }
}