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

时间:2014-08-07 06:57:09

标签: c# winforms button contextmenu

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

但是,当制作了许多这些过程时,并非所有块都能轻松适应屏幕。出于这个原因,我正在实现一个“紧凑模式”,它隐藏了所有过程块的所有按钮,只留下它们的名称,状态和开始/停止按钮。然后我为每个进程块分配一个ContextMenuStrip,在其中我显示列为ToolStripMenuItem的所有按钮,这样我就可以通过这种方式访问​​进程块的所有功能。我正在动态清除这些ContextMenuStrip并在菜单打开时添加项目。 我通过迭代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);
  }
}

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

3 个答案:

答案 0 :(得分:3)

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
        });

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

 cMenuStrip.Items.Add(new ToolStripMenuItem(
      lbl, btn.BackgroundImage, (s, ea) => ClickButton(btn)));

其中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;
}

答案 1 :(得分:1)

唯一不能做的是设置visible = false;

除了yu可以使用任何技巧来隐藏按钮:你可以将它们堆叠在另一个控件后面,你可以将它们从任何方向移出视线,甚至将它们移动到另一个父母:

隐藏它们:

panel1.Size = Size.Empty;
button1.Parent = panel1;
//..

再次展示:

button1.Parent = this;
//..

假设他们坐在表格上。

请注意,他们会保留原来的位置和大小;注意tab-order和z-order的变化!

答案 2 :(得分:0)

如果按钮不可见,则不会引发Click事件。 一种选择是获取按钮单击事件中的代码并将其作为单独的方法添加。然后调用方法而不是PerformClick行。如果您在每次按钮点击时执行相同的操作,这将有效。

使按钮透明的另一个选项。这将使它们对客户端不可见,并且PerformClick事件将正常工作。您可以在以下链接中看到:Drawing a transparent button

希望这有帮助。