我在WinForm上有一个DataGridView。当用户右键单击网格时,我显示一个弹出菜单。根据右键单击的位置,有3种弹出菜单:
我创建了一个新类来管理弹出菜单的生成。
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上完成。 例如,单击add,将打开包含所有必填字段的临时表单,然后此信息将作为DataGridView中的新行添加。
答案 0 :(得分:1)
在各个类的构造函数中。
答案 1 :(得分:1)
我相信它应该是这样的:
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;
}
}