在隐藏按钮上触发 Button.PerformClick()

Bar*_*ift 2 c# contextmenu button winforms

我正在开发一个 C# WinForms 应用程序,其中有许多进程都由“主”应用程序管理。在这个主应用程序中,每个进程都由它自己可视化,FlowLayoutPanel其中包含许多用于各种功能的按钮。我称这些面板为“进程块”。

然而,当进行许多这样的过程时,并不是所有的块都能轻松地适应屏幕。出于这个原因,我正在实施一个“紧凑模式”,它隐藏了所有进程块的所有按钮,只留下它们的名称、它们的状态和开始/停止按钮可见。然后我将 a 分配ContextMenuStrip给每个进程块,其中我将所有列出的按钮显示为 a,ToolStripMenuItem以便我可以通过这种方式访问​​进程块的所有功能。我正在ContextMenuStrip动态清除这些s 并在打开菜单时添加项目。我通过在所有迭代的子控件做到这一点FlowLayoutPanel,看看他们是否有类型的Button,如果是的话,我将它们添加到ContextMenuStrip。请参阅下面的代码片段:

private void PanelCmsOpened(object sender, EventArgs e) {
  try {
    ContextMenuStrip cMenuStrip = (ContextMenuStrip) sender;
    // Clear all items from the context menu
    cMenuStrip.Items.Clear();
    // Loop over all controls in the FlowLayoutPanel
    foreach (var c in CPanel.Controls) {
      Button btn = c as Button;
      if (btn == null) continue; // Not a button, continue
      // Get the text from the button
      string lbl = btn.Text;
      if (string.IsNullOrEmpty(lbl)) {
        try {
          // The button has no text (only an icon), so we get the tooltip text of the button
          lbl = PanelTooltip.GetToolTip(btn);
        }
        catch {
          // We can't get any text to display, so skip this button
          continue;
        }
      }
      // Add a new item to the ContextMenuStrip
      cMenuStrip.Items.Add(new ToolStripMenuItem(lbl,
                                                 btn.BackgroundImage,
                                                 (s, ea) => btn.PerformClick() // Perform a click on the button
                                                )
                                                {
                                                  Enabled = btn.Enabled
                                                });
    }
  }
  catch (Exception Ex) {
    MessageBox.Show("Fout bij openen van context menu: " + Ex.Message, "Fout", MessageBoxButtons.OK, MessageBoxIcon.Error);
  }
}
Run Code Online (Sandbox Code Playgroud)

问题:现在一切正常,只要按钮可见。但是,当进入紧凑模式时,我通过设置它们的Button.Visible属性来隐藏按钮。在这种情况下,什么都不会发生。我试过在 周围放置一个 try-catch 块PerformClick,但没有抛出异常。只是什么都没有发生。有谁知道如何使隐藏按钮工作?

Ser*_*kiy 5

PerformClick在执行单击之前检查按钮是否可用于单击。隐藏按钮被视为不可用。您可以在执行单击之前简单地显示按钮,并在单击后隐藏它:

 cMenuStrip.Items.Add(
     new ToolStripMenuItem(lbl, btn.BackgroundImage, (s, ea) => {
          var size = btn.Size;
          btn.Size = Size.Empty; // button still will be invisible
          btn.Show(); // make it clickable
          btn.PerformClick();
          btn.Hide();  // hide again
          btn.Size = size; // restore original size
        });
Run Code Online (Sandbox Code Playgroud)

注意:如果你还需要添加一些可见的按钮,那么你应该单独处理它们以避免闪烁

 cMenuStrip.Items.Add(new ToolStripMenuItem(
      lbl, btn.BackgroundImage, (s, ea) => ClickButton(btn)));
Run Code Online (Sandbox Code Playgroud)

ClickButton根据按钮是否可见,执行不同逻辑的方法在哪里:

private void ClickButton(Button button)
{
    if (button.Visible)
    {
        button.PerformClick();
        return;
    }

    var size = button.Size;
    button.Size = Size.Empty;
    button.Show();
    button.PerformClick();
    button.Hide();
    button.Size = size;
}
Run Code Online (Sandbox Code Playgroud)