Chris
Chris

Reputation: 39

How to create a dynamically built Context Menu clickEvent

I have a DataGridView and a context menu that opens when you right click a specific column. What shows up in the context menu is dependant on what's in the field clicked on - paths to multiple files (the paths are manipulated to create a full UNC path to the correct file).

The only problem is that I can't get the click working. I did not drag and drop the context menu from the toolbar, I created it programmically.

I figured that if I can get the path (let's call it ContextMenuChosen) to show up in MessageBox.Show(ContextMenuChosen); I could set the same to System.Diagnostics.Process.Start(ContextMenuChosen);

The Mydgv_MouseUp event below actually works to the point where I can get it to fire off MessageBox.Show("foo!"); when something in the context menu is selected but that's where it ends. I left in a bunch of comments below showing what I've tried when it one of the paths are clicked. Some result in empty strings, others error (Object not set to an instance...).

I searched code all day yesterday but couldn't find another way to hook up a dynamically built Context Menu clickEvent.

Code and comments:

    ContextMenu m = new ContextMenu();

    // SHOW THE RIGHT CLICK MENU
    private void Mydgv_MouseClick(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            int currentMouseOverCol = Mydgv.HitTest(e.X, e.Y).ColumnIndex;
            int currentMouseOverRow = Mydgv.HitTest(e.X, e.Y).RowIndex;

            if (currentMouseOverRow >= 0 && currentMouseOverCol == 6)
            {
                string[] paths = myPaths.Split(';');
                foreach (string path in paths)
                {
                    string UNCPath = "\\\\1.1.1.1\\c$\\MyPath\\";
                    string FilePath = path.Replace("c:\\MyPath\\", @"");
                    m.MenuItems.Add(new MenuItem(UNCPath + FilePath));
                }
            }
            m.Show(Mydgv, new Point(e.X, e.Y));
        }
    }



    // SELECTING SOMETHING IN THE RIGHT CLICK MENU
    private void Mydgv_MouseUp(object sender, MouseEventArgs e)
    {
        DataGridView.HitTestInfo hitTestInfo;
        if (e.Button == MouseButtons.Right)
        {
            hitTestInfo = Mydgv.HitTest(e.X, e.Y);
            // If column is first column
            if (hitTestInfo.Type == DataGridViewHitTestType.Cell && hitTestInfo.ColumnIndex == 6)
            {
                //MessageBox.Show(m.ToString());
                ////MessageBox.Show(m.Tag.ToString());
                //MessageBox.Show(m.Name.ToString());
                //MessageBox.Show(m.MenuItems.ToString());
                ////MessageBox.Show(m.MdiListItem.ToString());
                // MessageBox.Show(m.Name);
                //if (m.MenuItems.Count > 0)
                //MessageBox.Show(m.MdiListItem.Text);
                //MessageBox.Show(m.ToString());
                //MessageBox.Show(m.MenuItems.ToString());
                //Mydgv.ContextMenu.Show(m.Name.ToString());
                //MessageBox.Show(ContextMenu.ToString());
                //MessageBox.Show(ContextMenu.MenuItems.ToString());
                //MenuItem.text
                //MessageBox.Show(this.ContextMenu.MenuItems.ToString());

            }

            m.MenuItems.Clear();
        }

    }

I'm very close to completing this so any help would be much appreciated.

Upvotes: 2

Views: 15904

Answers (2)

Angshuman Agarwal
Angshuman Agarwal

Reputation: 4866

You may handle CellMouseDown like this when you when you right click a cell of a specific column. The specific column is achieved by e.ColumnIndex check

Aditionally, you can use GetCellDisplayRectangle instead of hittest

ContextMenu cm = new ContextMenu();

void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {

        if (e.ColumnIndex == 0)
        {
            cm.MenuItems.Clear();
            var mi = new MenuItem("C:\temp");
            mi.MenuItems.Add(mi);
            // handle menu item click event here [as required]
            mi.Click += OnMenuItemClick;
            cm.MenuItems.Add(0, mi);
            var bounds = dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false);
            if (sender != null)
            {
                cm.Show(sender as DataGridView, new Point(bounds.X, bounds.Y));
            }
        }
    }
}

 void OnMenuItemClick(object sender, EventArgs e)
 {
      MessageBox.Show(((MenuItem)sender).Text);
 }

Upvotes: 0

LarsTech
LarsTech

Reputation: 81620

I don't see an event handler wired to your menu item, so that something will happen when you click it:

void menu_Click(object sender, EventArgs e) {
  MessageBox.Show(((MenuItem)sender).Text);
}

Then attach it when you add the menu item to the context menu:

  MenuItem mi = new MenuItem(UNCPath + FilePath);
  mi.Click += menu_Click;
  m.MenuItems.Add(mi);

Upvotes: 2

Related Questions