右键单击打开自定义 ContextMenuStrip
Open custom ContextMenuStrip on right-click
我正在创建一个包含不同类型 TreeNode 的 TreeView,每个 TreeNode 都有自己的 ContextMenuStrip 菜单。
我有一个继承自 TreeNode
的 class ElementTreeNode
。我想添加一个继承自 ContextMenuStrip
菜单的 ElementContextMenu
,右键单击节点时应打开该菜单。
我的第一个方法是简单地将 ElementContextMenu
的实例添加到我的 ElementTreeNode
的 ContextMenuStrip
属性 中。但是我向 ElementTreeNode
添加了一个 EventHandler,我无法通过这种方式访问它。可能是因为 属性 向下转换为 ContextMenuStrip
从而丢失了仅存在于 ElementContextMenu
:
中的 EventHandler
class ElementTreeNode : TreeNode
{
public ElementTreeNode()
{
ContextMenuStrip = new ElementContextMenu();
}
}
我的第二个想法是在 class 中添加一个 属性 ElementContextMenu 然后让右键单击事件打开此菜单而不是 ContextMenuStrip 属性:
class ElementTreeNode : TreeNode
{
public ElementContextMenu ElementContextMenu;
public ElementTreeNode()
{
ElementContextMenu = new ElementContextMenu();
}
}
所以我的问题是:
如何在右键单击节点时打开 ElementContextMenu
属性 而不是 ContextMenuStrip
?
有没有办法改变这种行为?
只需手动显示 ContextMenu
,不要分配 TreeView
的上下文菜单。例如
TreeView tv = new TreeView() { Dock = DockStyle.Fill };
tv.Nodes.Add(new ElementTreeNode { Text = "Node 1" });
tv.Nodes.Add(new ElementTreeNode { Text = "Node 2" });
tv.MouseDown += (o, e) => {
TreeNode n = tv.GetNodeAt(e.Location);
tv.SelectedNode = n; // known bug, force selected node
if (e.Button == MouseButtons.Right) {
if (n is ElementTreeNode) {
var n2 = (ElementTreeNode) n;
n2.ElementContextMenu.Show(tv, e.Location);
}
}
};
试着让你的 ElementTreeNode
class 像这样:
class ElementTreeNode : TreeNode
{
public ElementTreeNode()
{
ElementContextMenu = new ElementContextMenu();
}
public ElementContextMenu ElementContextMenu
{
get {
return ContextMenuStrip as ElementContextMenu;
}
private set {
ContextMenuStrip = value;
}
}
}
现在,只要您需要添加事件处理程序或访问仅存在于 ElementContextMenu
class 中的属性,请使用 ElementContextMenu
属性。
old ContextMenuStrip
属性 的行为仍然相同(右键单击节点时打开上下文菜单),但它会打开您的 ElementContextMenu
实例。
我正在创建一个包含不同类型 TreeNode 的 TreeView,每个 TreeNode 都有自己的 ContextMenuStrip 菜单。
我有一个继承自 TreeNode
的 class ElementTreeNode
。我想添加一个继承自 ContextMenuStrip
菜单的 ElementContextMenu
,右键单击节点时应打开该菜单。
我的第一个方法是简单地将 ElementContextMenu
的实例添加到我的 ElementTreeNode
的 ContextMenuStrip
属性 中。但是我向 ElementTreeNode
添加了一个 EventHandler,我无法通过这种方式访问它。可能是因为 属性 向下转换为 ContextMenuStrip
从而丢失了仅存在于 ElementContextMenu
:
class ElementTreeNode : TreeNode
{
public ElementTreeNode()
{
ContextMenuStrip = new ElementContextMenu();
}
}
我的第二个想法是在 class 中添加一个 属性 ElementContextMenu 然后让右键单击事件打开此菜单而不是 ContextMenuStrip 属性:
class ElementTreeNode : TreeNode
{
public ElementContextMenu ElementContextMenu;
public ElementTreeNode()
{
ElementContextMenu = new ElementContextMenu();
}
}
所以我的问题是:
如何在右键单击节点时打开 ElementContextMenu
属性 而不是 ContextMenuStrip
?
有没有办法改变这种行为?
只需手动显示 ContextMenu
,不要分配 TreeView
的上下文菜单。例如
TreeView tv = new TreeView() { Dock = DockStyle.Fill };
tv.Nodes.Add(new ElementTreeNode { Text = "Node 1" });
tv.Nodes.Add(new ElementTreeNode { Text = "Node 2" });
tv.MouseDown += (o, e) => {
TreeNode n = tv.GetNodeAt(e.Location);
tv.SelectedNode = n; // known bug, force selected node
if (e.Button == MouseButtons.Right) {
if (n is ElementTreeNode) {
var n2 = (ElementTreeNode) n;
n2.ElementContextMenu.Show(tv, e.Location);
}
}
};
试着让你的 ElementTreeNode
class 像这样:
class ElementTreeNode : TreeNode
{
public ElementTreeNode()
{
ElementContextMenu = new ElementContextMenu();
}
public ElementContextMenu ElementContextMenu
{
get {
return ContextMenuStrip as ElementContextMenu;
}
private set {
ContextMenuStrip = value;
}
}
}
现在,只要您需要添加事件处理程序或访问仅存在于 ElementContextMenu
class 中的属性,请使用 ElementContextMenu
属性。
old ContextMenuStrip
属性 的行为仍然相同(右键单击节点时打开上下文菜单),但它会打开您的 ElementContextMenu
实例。