如何在单击项目后打开ToolStripMenu

时间:2012-11-12 19:27:24

标签: c# winforms user-interface menu menuitem

我正在创建一个ToolStripMenu,它应该允许用户与“XML”和“非XML”项交互,就好像它们是表单上的常规复选框一样。但是,当选中/取消选中一个项目时,菜单将关闭。如何在不关闭菜单的情况下允许选中/取消选中项目?或者是否有不同的标准方法来实现相同的行为?

enter image description here

所以我想要的是能够点击“非XML”,显示一个复选框并打开菜单。 这个想法是最后一个菜单项将是“完成”,当它被点击时,“G2S”子项将保持打开状态,但“显示”子项(XML,非XML)将关闭。

有什么想法吗?

注意:我知道这可能不是最好的用户界面设计。我想知道如何才能获得有关处理菜单的技术知识。

6 个答案:

答案 0 :(得分:4)

有趣的概念在this thread on Stackoverflow中描述:

这是接受答案的本质:

ParentMenu.DropDown.AutoClose = false;

它完全符合您的要求 - 在单击子项目时阻止菜单关闭。

答案 1 :(得分:2)

这是一个有用的扩展,要求用户点击菜单项+下拉菜单以外关闭。

    public static void KeepOpenOnDropdownCheck (this ToolStripMenuItem ctl)
    {
        foreach (var item in ctl.DropDownItems.OfType<ToolStripMenuItem>())
        {
            item.MouseEnter += (o, e) => ctl.DropDown.AutoClose = false;
            item.MouseLeave += (o, e) => ctl.DropDown.AutoClose = true;
        }

    }

答案 2 :(得分:1)

张贴以防有人发现它有用。

我没有尝试完全按照我原先的意图行事,而是提出以下建议:

1-使用ContextMenuStrip
2-当用户点击ToolStripMenu项时,我会在菜单项附近的位置显示ContextMenuStrip,如下所示:(注意定位仍需要调整)

enter image description here

为了实现这一点,我在运行时在代码中构建ContextMenuStrip,以便根据情况动态构建ContextMenuStrip中的项目。

代码段:

单击菜单项时显示ContextMenuStrip

private void filterToolStripMenuItem_Click(object sender, EventArgs e)
{
    contextMenuStrip1.Show(this, 180, 20);
}

构建ContextMenuStrip

    if (protInfo.Name == "QCOM" )
    {
        BroadCast = new CheckBox();
        BroadCast.Text = "Date/Time Broadcast";
        BroadCast.Checked = FlagSet(CurrentFilter, (Byte)Filter.DateTimeBC);
        ToolStripControlHost Ch1 = new ToolStripControlHost(BroadCast);

        GenPoll = new CheckBox();
        GenPoll.Text = "Status Poll";
        GenPoll.Checked = FlagSet(CurrentFilter, (Byte)Filter.GenStatusPoll);
        ToolStripControlHost Ch2 = new ToolStripControlHost(GenPoll);

        GenPollResp = new CheckBox();
        GenPollResp.Text = "Status Poll Response";
        GenPollResp.Checked = FlagSet(CurrentFilter, (Byte)Filter.GenStatusResponse);
        ToolStripControlHost Ch3 = new ToolStripControlHost(GenPollResp);

        Button btnDone = new Button();
        btnDone.Text = "Done";
        ToolStripControlHost Ch4 = new ToolStripControlHost(btnDone);
        btnDone.Click += new EventHandler(btnDone_Click);

        contextMenuStrip1.Items.Clear();
        contextMenuStrip1.Items.Add(Ch1);
        contextMenuStrip1.Items.Add(Ch2);
        contextMenuStrip1.Items.Add(Ch3);
        contextMenuStrip1.Items.Add(Ch4);
        contextMenuStrip1.Enabled = true;
        filterToolStripMenuItem.Enabled = true;
    }
    else
    {
        filterToolStripMenuItem.Enabled = false;
    }

这可能不是最好的用户界面设计,但它似乎有效。

答案 3 :(得分:1)

我使用了Neolisk和Chimera的答案组合,允许从树视图中删除多个叶子项目。我的解决方案如下

注意:使用在设计时创建的以下项目:   TreePromotions(TreeView)   menuVendorSection(上下文菜单条)   removeMultipleItemsToolStripMenuItem(menuVendorSection的DropDown)

 private void removeMultipleItemsToolStripMenuItem_MouseHover(object sender, EventArgs e)
    {
        removeMultipleItemsToolStripMenuItem.DropDownItems.Clear();  
        ToolStripMenuItem detailMenuItem;
        TreeNode vendorSectionNode = treePromotions.SelectedNode;
        for (int vsn = 0; vsn < vendorSectionNode.Nodes.Count; vsn++)
        {
            //add checkbox item
            detailMenuItem = new ToolStripMenuItem(vendorSectionNode.Nodes[vsn].Text);
            detailMenuItem.Tag = vendorSectionNode.Nodes[vsn].Tag;
            detailMenuItem.CheckOnClick = true;
            removeMultipleItemsToolStripMenuItem.DropDownItems.Add(detailMenuItem);

        }
        //add action buttons
        Button buttonDeleteMultiple = new Button();
        buttonDeleteMultiple.Text = "Remove Checked Items";
        ToolStripControlHost buttonHost = new ToolStripControlHost(buttonDeleteMultiple);
        buttonDeleteMultiple.Click += new EventHandler(buttonDeleteMultiple_Click);
        removeMultipleItemsToolStripMenuItem.DropDownItems.Add(buttonHost);

        Button buttonCancelMultipleDelete = new Button();
        buttonCancelMultipleDelete.Text = "CANCEL";
        buttonHost = new ToolStripControlHost(buttonCancelMultipleDelete);
        buttonCancelMultipleDelete.Click += new EventHandler(buttonCancelMultipleDelete_Click);
        removeMultipleItemsToolStripMenuItem.DropDownItems.Add(buttonHost);



        removeMultipleItemsToolStripMenuItem.DropDown.AutoClose = false;
        menuVendorSection.AutoClose = false;





    }

    private void buttonDeleteMultiple_Click(object sender, EventArgs e)
    {

        //delete items
        for (int dmi = 0; dmi < removeAllItemsToolStripMenuItem.DropDownItems.Count - 2; dmi++) //do not include buttons
        {
            ((Detail)removeAllItemsToolStripMenuItem.DropDownItems[dmi].Tag).Delete(); //deletes item from database
        }
        //rebuild leaf
        treePromotions.SelectedNode.Nodes.Clear();
        addItemNodes(treePromotions.SelectedNode);  //builds leaf nodes from database

        //close menus
        removeMultipleItemsToolStripMenuItem.DropDown.Close();
        menuVendorSection.AutoClose = true;
        menuVendorSection.Close();
    }

    private void buttonCancelMultipleDelete_Click(object sender, EventArgs e)
    {
        //just close menus
        removeMultipleItemsToolStripMenuItem.DropDown.Close();
        menuVendorSection.AutoClose = true;
        menuVendorSection.Close();
    }

And here is what it looks like

答案 4 :(得分:1)

如果有人仍然感兴趣,这是vb解决方案:

1)对于父工具条菜单项,在表单的构造函数中添加以下处理程序:

AddHandler ParentTSMI.DropDown.Closing, AddressOf onDropDownClosing

2)处理程序:

Private Sub onDropDownClosing(sender As Object, e As ToolStripDropDownClosingEventArgs)
    If e.CloseReason = ToolStripDropDownCloseReason.ItemClicked Then
        e.Cancel = True
    End If
End Sub

仅此而已。

在关闭表单时不要忘记删除处理程序(RemoveHandler)。

答案 5 :(得分:0)

原始解决方案适用于鼠标事件。

鼠标输入事件:

parent.dropdown.autoclose = false;

鼠标离开事件:

parent.dropdown.autoclose = true;

唯一的问题是用户是否通过鼠标以外的其他方式访问菜单项。