如何使用鼠标右键单击ContextMenu上的特定项目?

时间:2014-06-07 03:43:42

标签: c# .net winforms

这是一个dataGridView1鼠标单击的事件,当我单击鼠标右键打开一个contextmenu。 在这种情况下有4个项目。 我希望最后一项用红色着色。 我可以禁用最后一项,但我现在要为它着色。

private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                ContextMenu m = new ContextMenu();
                m.MenuItems.Add(new MenuItem("Cut"));
                m.MenuItems.Add(new MenuItem("Copy"));
                m.MenuItems.Add(new MenuItem("Paste"));

                int currentMouseOverRow = dataGridView1.HitTest(e.X, e.Y).RowIndex;

                if (currentMouseOverRow >= 0)
                {
                    m.MenuItems.Add(new MenuItem(string.Format("Row number {0}", currentMouseOverRow.ToString())));
                    m.MenuItems[m.MenuItems.Count - 1].OwnerDraw = true;
                    m.MenuItems[m.MenuItems.Count - 1].DrawItem += Cm_DrawItem;
                    //m.MenuItems[m.MenuItems.Count -1].Enabled = false;
                }

                m.Show(dataGridView1, new Point(e.X, e.Y));

            }
        }

这是Cm_DrawItem事件:

void Cm_DrawItem(object sender, DrawItemEventArgs e)
        {
            var item = (MenuItem)sender;
            var g = e.Graphics;
            var font = new Font("Arial", 10, FontStyle.Italic);
            var brush = new SolidBrush(e.ForeColor);
            g.DrawString(item.Text, font, brush, e.Bounds.X, e.Bounds.Y);
        }

我使用了一个断点并且它正在进入Cm_DrawItem事件,但它并没有给它上色。然后,当使用此Cm_DrawItem事件时,我现在只看到3个项目。

修改

这是我根据解决方案更改代码后现在得到的结果:

enter image description here

这是现在的代码:

private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                ContextMenu m = new ContextMenu();
                m.MenuItems.Add(new MenuItem("Cut"));
                m.MenuItems.Add(new MenuItem("Copy"));
                m.MenuItems.Add(new MenuItem("Paste"));

                int currentMouseOverRow = dataGridView1.HitTest(e.X, e.Y).RowIndex;

                if (currentMouseOverRow >= 0)
                {
                    m.MenuItems[m.MenuItems.Count - 1].OwnerDraw = true;
                    m.MenuItems[m.MenuItems.Count - 1].DrawItem += Cm_DrawItem;
                    m.MenuItems.Add(new MenuItem(string.Format("Row number {0}", currentMouseOverRow.ToString())));

                    //m.MenuItems[m.MenuItems.Count -1].Enabled = false;
                }

                m.Show(dataGridView1, new Point(e.X, e.Y));

            }
        }

事件:

void Cm_DrawItem(object sender, DrawItemEventArgs e)
        {
            var item = (MenuItem)sender;
            var g = e.Graphics;
            var font = new Font("Arial", 10, FontStyle.Italic);
            var brush = new SolidBrush(System.Drawing.Color.Red);
            g.DrawString(item.Text, font, brush, e.Bounds.X, e.Bounds.Y);
        }

但我想让它为这一行的整行着色:

m.MenuItems.Add(new MenuItem(string.Format("Row number {0}", currentMouseOverRow.ToString())));

例如,如果我在第5行上单击鼠标右键,那么文本:行号5应为红色,包括数字。

但正如你在屏幕截图中看到的那样,它会为其他东西着色。

修改

我现在也看到鼠标点击事件中的代码应该像以前一样:

m.MenuItems.Add(new MenuItem(string.Format("Row number {0}", currentMouseOverRow.ToString())));
m.MenuItems[m.MenuItems.Count - 1].OwnerDraw = true;
m.MenuItems[m.MenuItems.Count - 1].DrawItem += Cm_DrawItem;

如果我将在第一个解决方案中更改它,那么将传递给着色的文本将是粘贴,因为我还没有添加Ro编号行...

并且以正确的方式为它着色。

2 个答案:

答案 0 :(得分:2)

您需要在上下文菜单中测量所有者绘制项目的项目大小(不知道这是一个错误还是故意的 - 没有找到任何关于此的文档)。

试试这个:

if (currentMouseOverRow >= 0)
{
    m.MenuItems.Add(new MenuItem(string.Format("Row number {0}", currentMouseOverRow.ToString())));
    m.MenuItems[m.MenuItems.Count - 1].OwnerDraw = true;
    m.MenuItems[m.MenuItems.Count - 1].DrawItem += Cm_DrawItem;
    m.MenuItems[m.MenuItems.Count - 1].MeasureItem += MeasureMenuItem;
}

void MeasureMenuItem(object sender,MeasureItemEventArgs e)
{
    MenuItem m = (MenuItem) sender;
    Font font = new Font(Font.FontFamily, Font.Size, Font.Style);
    SizeF sze = e.Graphics.MeasureString(m.Text, font);
    e.ItemHeight = (int)sze.Height;
    e.ItemWidth = (int)sze.Width;
}

目前,您的菜单项将以默认颜色绘制。如果你想改变颜色,你应该按照@ C-Pound的解决方案在Cm_DrawItem中进行。

var brush = new SolidBrush(Color.Red); //or whatever color you want.

注意:所有者绘制的项目意味着您必须完全绘制项目,这意味着您必须偏移左侧图像的绘图。

编辑:附加说明
您还可以更改度量项中菜单项的大小,通常+4,高度和宽度看起来不错,

e.ItemHeight = (int)sze.Height+4;
e.ItemWidth = (int)sze.Width+4;

在Drawing例程中,偏移量为+16使菜单项与其他项对齐。

g.DrawString(item.Text, font, brush, e.Bounds.X+16, e.Bounds.Y);

答案 1 :(得分:0)

从一开始你就是在做所有事情。 只需要为菜单项

添加此事件处理程序
m.MenuItems[m.MenuItems.Count - 1].MeasureItem += menuItem2_MeasureItem;

并定义相应的事件处理程序:

private void menuItem2_MeasureItem(object sender,System.Windows.Forms.MeasureItemEventArgs e)
        {
            e.ItemWidth = 75;
            e.ItemHeight = 18;
        }

它会解决您的问题。我和你的情况一样,对我有用。 有关更多详细信息:参考

http://www.c-sharpcorner.com/article/owner-draw-menus-in-C-Sharp/

祝你好运, 人士Himanshu