4

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

在此处输入图像描述

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

有任何想法吗?

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

4

6 回答 6

4

Stackoverflow 上的这个线程描述了一个有趣的概念:

这是公认答案的本质:

ParentMenu.DropDown.AutoClose = false;

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

于 2012-11-13T01:18:31.363 回答
3

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

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

    }
于 2018-05-17T10:33:13.020 回答
1

发布以防有人发现它有帮助。

我没有尝试完全按照我最初的意图去做,而是提出了以下建议:

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

在此处输入图像描述

为了让它工作,我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;
    }

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

于 2012-11-13T00:31:59.657 回答
1

原始解决方案将使用鼠标事件。

鼠标输入事件:

parent.dropdown.autoclose = false;

鼠标离开事件:

parent.dropdown.autoclose = true;

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

于 2012-11-27T10:01:36.857 回答
1

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

注意:使用了以下在设计时创建的 Item: TreePromotions (TreeView) menuVendorSection (Context Menu Strip) removeMultipleItemsToolStripMenuItem (DropDown of menuVendorSection)

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

这就是它的样子

于 2015-10-17T01:32:31.667 回答
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)。

于 2018-08-14T22:31:00.897 回答