Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过从其他窗体继承的ContextMenu子菜单检索DataGridView中的对象_C#_Winforms_Inheritance_Datagridview_Contextmenu - Fatal编程技术网

C# 通过从其他窗体继承的ContextMenu子菜单检索DataGridView中的对象

C# 通过从其他窗体继承的ContextMenu子菜单检索DataGridView中的对象,c#,winforms,inheritance,datagridview,contextmenu,C#,Winforms,Inheritance,Datagridview,Contextmenu,我有一个有多种形式的项目。其中许多表单都有一个带有数据绑定项的DataGridView,它们绑定到类票证的实例。我想给所有这些DataGridView提供相同的ContextMenu。当用户右键单击DataGridView中的一行,然后单击contextmenu中的一项时,必须对数据绑定的票证进行处理 为了实现这一点,我创建了一个基础表单,其他表单从中继承。在这个基本表单中,我定义了ContextMenu(我以前没有使用过ContextMenu,所以它是反复试验的,我不确定这是最好的方法。):

我有一个有多种形式的项目。其中许多表单都有一个带有数据绑定项的DataGridView,它们绑定到类
票证的实例。我想给所有这些DataGridView提供相同的ContextMenu。当用户右键单击DataGridView中的一行,然后单击contextmenu中的一项时,必须对数据绑定的
票证进行处理

为了实现这一点,我创建了一个基础表单,其他表单从中继承。在这个基本表单中,我定义了ContextMenu(我以前没有使用过ContextMenu,所以它是反复试验的,我不确定这是最好的方法。):

其思想是:上下文菜单有3个菜单项;编辑、设置固定和分配。分配项有一个子菜单,该子菜单动态填充存储在
选择
实例中的
用户
。这些菜单和子菜单在继承自基础表单的表单中创建得非常好

“Set Fixed”(设置已修复)项目背后的功能我正在工作,我检索相关的
票据
,如下所示:

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;
    }    
}
但是,我无法从分配项目的子菜单中检索所选的
票据。当我从一个子菜单出来时,
clickedItem.Owner
是一个
ToolStripDropDownMenu
,我似乎再也无法进入
DataGridView
级别了


如何从ContextMenu的子菜单获取DataGridView中原始单击行(即
票证
)?

在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;
就查找当前索引而言,在该方法正常工作之前,用户必须已经单击了某些内容。。。因此,明智的做法是在那里进行检查,以确保这项工作已经完成


希望这有帮助

看起来不错!没有想到使用gridview事件。我会在星期一测试。这可能意味着我也必须让gridview遗传,不是吗?或者如果它们的名称相同就足够了吗?DataGridView的名称应该无关紧要。不过,重要的是将方法连接到正确的鼠标单击事件。否则,您将没有正确的MouseEventArgs对象(这将使显示菜单更加困难)。如果选择,您应该能够对每个DataGridView使用相同的事件处理方法。用于此目的的是
CellClick
事件。我认为你根本不需要编辑你的DataGridView来实现这一点。对,这很有意义。到目前为止非常感谢,当我尝试它时,可能会给你回复。这比我想象的要容易得多!非常感谢你的帮助。
DataGridView dgv = (DataGridView) sender;
Ticket currentTicket = (Ticket) dgv.CurrentRow.DataBoundItem;