ehh
ehh

Reputation: 3480

Where to define the menu items event handler

I have a DataGridView on a WinForm. When the user right-click on the grid, I am showing a popup menu. There are 3 kinds of popup menu according to where the right-click has been done:

  1. on a row that is defined as readonly
  2. on a row that can be edited
  3. on any other place in the grid (rowindex is -1)

I created a new classes to manage the popup menus generation.

public class GridPopupMenuFactory
{
    public ContextMenu GetMenu(int rowIndex, bool isReadOnlyRow)
    {
        BaseMenu _menu = null;

        switch (rowIndex)
        {
            case -1:
                _menu = new GeneralMenu();
                break;
            default:
                if (isReadOnlyRow)
                {
                    _menu = new ReadonlyRowMenu();
                }
                else
                {
                    _menu = new EditableRowMenu();
                }
                break;
        }

        return _menu.Menu;
    }
}

public abstract class BaseMenu
{
    protected ContextMenu _menu;
    public ContextMenu Menu
    {
        get
        {
            if (_menu.MenuItems.Count == 0)
            {
                GenerateMenu();
            }
            return _menu;
        }
    }

    protected abstract void GenerateMenu();
}

public class GeneralMenu : BaseMenu
{
    protected override void GenerateMenu()
    {
        var contextMenu = new ContextMenu();

        contextMenu.MenuItems.Add(new MenuItem("Sort"));
        contextMenu.MenuItems.Add(new MenuItem("Print"));            

        _menu = contextMenu;
    }
}

public class ReadonlyRowMenu : BaseMenu
{
    protected override void GenerateMenu()
    {
        var contextMenu = new ContextMenu();

        contextMenu.MenuItems.Add(new MenuItem("View"));            

        _menu = contextMenu;
    }
}

public class EditableRowMenu : BaseMenu
{
    protected override void GenerateMenu()
    {
        var contextMenu = new ContextMenu();

        contextMenu.MenuItems.Add(new MenuItem("Add"));
        contextMenu.MenuItems.Add(new MenuItem("Edit"));
        contextMenu.MenuItems.Add(new MenuItem("Delete"));

        _menu = contextMenu;
    }
}

// Winform
private void shipmentDetailsDataGridView_MouseClick(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            var rowIndex = shipmentDetailsDataGridView.HitTest(e.X, e.Y).RowIndex;
            var popupMenu = GridPopupMenu.GetMenu(rowIndex, false);  // 2nd parameter can be true, TODO

            popupMenu.Show(shipmentDetailsDataGridView, new Point(e.X, e.Y));
        }
    }

My question is where is the correct place to define the event handler for each one of the menu items?

Update: After clicking on the menu item, the whole operation is done on the DataGridView itself. For example, clicking on add, will open a temp form with all the required field and then this information will be added as a new row in the DataGridView.

Upvotes: 0

Views: 76

Answers (2)

DmitryG
DmitryG

Reputation: 17850

I believe it should looks like this:

public class GeneralMenu : BaseMenu {
    protected override void GenerateMenu() {
        var contextMenu = new ContextMenu();
        contextMenu.MenuItems.Add(new MenuItem("Sort", OnSort));
        contextMenu.MenuItems.Add(new MenuItem("Print", OnPrint));
        _menu = contextMenu;
    }
    void OnSort(object sender, EventArgs e) {
        var gridView = GetSourceControl<DataGridView>(sender);
        if(gridView != null) {
            // do sort
        }
    }
    void OnPrint(object sender, EventArgs e) {
        var gridView = GetSourceControl<DataGridView>(sender);
        if(gridView != null) {
            // do print
        }
    }
    static TControl GetSourceControl<TControl>(object sender) where TControl : Control {
        var menu = ((MenuItem)sender).GetContextMenu();
        return (menu != null) ? menu.SourceControl as TControl : null;
    }
}

Upvotes: 1

Isuru
Isuru

Reputation: 450

In the constructor of respective classes.

Upvotes: 1

Related Questions