我有一个包含多个表单的项目。其中许多表单都有DataGridView和DataBound项,它们绑定到类Ticket
的实例。我想给所有这些DataGridViews相同的ContextMenu。当用户右键单击DataGridView中的某一行,然后单击上下文菜单中的某个项目时,必须使用数据绑定Ticket
完成某些操作。
为实现这一目标,我创建了一个基本表单,其他表单继承自。在这个基本形式中,我定义了ContextMenu(我以前没有使用上下文菜单,所以它是反复试验,我不确定这是最好的方法。 ):
public ContextMenuStrip ContextTicket;
public frmBaseForm()
{
InitializeComponent();
ContextTicket = new ContextMenuStrip();
var itemEdit = ContextTicket.Items.Add("Edit ");
itemEdit.Click += itemEdit_Click;
var itemAssign = ContextTicket.Items.Add("Assign to");
foreach (var user in Selection.Users)
{
ToolStripItem item = (itemAssign as ToolStripMenuItem).DropDownItems.Add(user.Name);
item.Click += itemAssign_Click;
}
var itemSetToFixed = ContextTicket.Items.Add("Set Fixed");
itemSetToFixed.Click += itemSetToFixed_Click;
}
这个想法是:上下文菜单有3个菜单项;编辑,设置固定和分配。 Assign Item有一个子菜单,它由users
实例中存储的Selection
动态填充。这些菜单和子菜单都以从基本形式继承的形式完美地创建。
" Set Fixed"背后的功能;我开始工作的项目,我像这样检索相关的Ticket
:
public void itemSetToFixed_Click(object sender, EventArgs e)
{
var ticket = getTicket(sender);
/*
Do something with Ticket
*/
}
private Ticket getTicket(object sender)
{
try
{
ToolStripItem clickedItem = sender as ToolStripItem;
ContextMenuStrip owner = clickedItem?.Owner as ContextMenuStrip;
DataGridView control = owner?.SourceControl as DataGridView;
var obj = control?.SelectedRows[0].DataBoundItem;
if (obj is Ticket)
{
return (Ticket)obj;
}
else
{
return null;
}
}
catch (Exception e)
{
MessageBox.Show("Error", "Unable to retrieve ticket information from selection.");
return null;
}
}
但是,我无法从分配项的子菜单中检索选定的Ticket
。当我来自子菜单时,clickedItem.Owner
是ToolStripDropDownMenu
,我似乎无法进入DataGridView
级别。
如何从ContextMenu的子菜单中获取DataGridView中原始点击的行(即Ticket
)?
答案 0 :(得分:1)
在DataGridView鼠标单击事件侦听方法上,将发件人视为DataGridView:
private void DataGridViewMouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
DataGridView dgv = sender as DataGridView;
if (dgv != null)
{
// find the current index
int currentIndex = dgv.CurrentRow.Index;
// find the current Ticket
Ticket currentTicket = dgv.CurrentRow.DataBoundItem as Ticket;
ContextMenu menu = new ContextMenu();
// set up the context menu here...
menu.Show(dgv, new Point(e.X, e.Y));
}
}
}
如果您愿意,可以使用另一种方式指定dgv和currentTicket对象:
DataGridView dgv = (DataGridView) sender;
Ticket currentTicket = (Ticket) dgv.CurrentRow.DataBoundItem;
就查找当前索引而言,用户必须在此方法正常工作之前已经点击了某些内容...因此,将检查放在那里以确保已完成此操作是明智的。
希望这有帮助!