我正在创建一个ToolStripMenu
,它应该允许用户与“XML”和“非XML”项交互,就好像它们是表单上的常规复选框一样。但是,当选中/取消选中一个项目时,菜单将关闭。如何在不关闭菜单的情况下允许选中/取消选中项目?或者是否有不同的标准方法来实现相同的行为?
所以我想要的是能够点击“非XML”,显示一个复选框并打开菜单。 这个想法是最后一个菜单项将是“完成”,当它被点击时,“G2S”子项将保持打开状态,但“显示”子项(XML,非XML)将关闭。
有什么想法吗?
注意:我知道这可能不是最好的用户界面设计。我想知道如何才能获得有关处理菜单的技术知识。
答案 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
,如下所示:(注意定位仍需要调整)
为了实现这一点,我在运行时在代码中构建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();
}
答案 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;
唯一的问题是用户是否通过鼠标以外的其他方式访问菜单项。