定义菜单项事件处理程序的位置

本文关键字:位置 程序 事件处理 菜单项 定义 | 更新日期: 2023-09-27 18:32:09

我在WinForm上有一个DataGridView。 当用户右键单击网格时,我显示一个弹出菜单。根据右键单击的位置,有3种弹出菜单:

  1. 在定义为只读的行上
  2. 在可以编辑的行上
  3. 在网格中的任何其他位置(行索引为 -1)

我创建了一个新类来管理弹出菜单的生成。

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));
        }
    }

我的问题是为每个菜单项定义事件处理程序的正确位置在哪里?

更新:单击菜单项后,整个操作将在 DataGridView 本身上完成。例如,单击"添加"将打开一个包含所有必填字段的临时窗体,然后将此信息作为新行添加到 DataGridView 中。

定义菜单项事件处理程序的位置

我相信它应该是这样的:

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;
    }
}

在各个类的构造函数中。