2

我有一个 TreeView 控件,其中的每个节点我想共享一个具有两个 ToolStripMenuItem 的 ContextMenuStrip,即:

this.BuildTree = new MyApp.MainForm.TreeView();
this.ItemMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.DeleteMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ShowLogMenuItem = new System.Windows.Forms.ToolStripMenuItem();
...
this.ItemMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.DeleteMenuItem,
this.ShowLogMenuItem});

因此,我在 MouseUp 事件中右键单击时根据某些条件显示和隐藏这些项目。当两者都被隐藏时,我隐藏了 ContextMenuStrip 本身。问题是当我隐藏 ContextMenuStrip 时,似乎下次我想显示其中一个菜单项时,我必须在节点上单击两次。奇怪的是在第一次单击以重新显示一个或两个项目时,我有以下代码:

ItemMenuStrip.Visible = true;
ShowLogMenuItem.Visible = true;

上面的两行似乎没有做任何事情,即在跨过每一行之后在调试器视图中都保持错误。

我认为我没有设置这些值的任何事件,至少我没有附加任何事件。

我究竟做错了什么?

4

2 回答 2

3

我建议你设置:

this.BuildTree.ContextMenuStrip = this.ItemMenuStrip;

使菜单在树右键单击时自动打开。

然后订阅ItemMenuStrip.Opening事件以更改项目的可见性和上下文菜单本身:

void ItemMenuStrip_Opening(object sender, CancelEventArgs e)
{
    if (something)
    {
        e.Cancel = true; // don't show the menu
    }
    else
    {
        // show/hide the items...
    }
}

如果您需要知道被点击点的当前位置(例如检查树节点是否被点击),您可以使用Control.MousePosition属性。请注意,这MousePosition是屏幕坐标中的一个点,因此您需要调用treeView1.PointToClient(position)以获取树坐标,例如:

private void ItemMenuStrip_Opening(object sender, CancelEventArgs e)
{
    var pointClicked = this.BuildTree.PointToClient(Control.MousePosition);
    var nodeClicked = this.BuildTree.GetNodeAt(pointClicked);
    if (nodeClicked == null) 
    {
        // no tree-node is clicked --> don't show the context menu
        e.Cancel = true;
    }
    else
    {
        // nodeClicked variable is the clicked node;
        // show/hide the context menu items accordingly
    }
}
于 2012-03-19T17:56:45.837 回答
0

所以弄清楚出了什么问题,我在 this.ItemMenuStrip 而不是 this.BuildTree.ContextMenuStrip 上设置了 Visible。

这对我来说似乎很奇怪,因为我认为 BuildTree.ContextMenuStrip 只是对 ItemMenuStrip 的直接引用,但显然不是。

于 2012-03-20T11:46:04.867 回答