C# 如何确定触发单击事件的位置

C# 如何确定触发单击事件的位置,c#,click,C#,Click,在windows窗体上,我有图片框,每个都有条带菜单项。PictureBoxes位于单独的类中。当用户单击一个StripMenuItem时,我如何确定单击了哪个PictureBox 我看过一些关于如何处理发送者的帖子,但是在属性中我看不到任何与点击项目相关的内容 以下是我的基本代码: public Form1() { InitializeComponent(); ContextMenu cm = new ContextMenu();

在windows窗体上,我有
图片框
,每个都有
条带菜单
项。
PictureBoxes
位于单独的类中。当用户单击一个
StripMenuItem
时,我如何确定单击了哪个
PictureBox

我看过一些关于如何处理发送者的帖子,但是在属性中我看不到任何与点击项目相关的内容

以下是我的基本代码:

    public Form1()
    {
        InitializeComponent();

        ContextMenu cm = new ContextMenu();
        MenuItem mi = new MenuItem()
        {
            Text = "click me"
        };
        mi.Click += new EventHandler(mi_Click);
        cm.MenuItems.Add(mi);


        Data d1 = new Data();
        d1.px.Location = new Point(30, 30);
        d1.px.ContextMenu = cm;

        Data d2 = new Data();
        d2.px.Location = new Point(100, 100);
        d2.px.ContextMenu = cm;

        Controls.Add(d1.px);
        Controls.Add(d2.px);

    }

    void mi_Click(object sender, EventArgs e)
    {
        var s = sender;
    }
    class Data
    {
        public PictureBox px = new PictureBox
        {
            Size = new Size(40, 40),
            BackColor = Color.Red
        };
    }
抱歉,如果这个问题已经被问到了,但我不知道如何搜索答案


提前感谢

您可以通过以下代码获得ContextMenuStrip的父级

private void testClickToolStripMenuItem_Click(object sender, EventArgs e)
{
    ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
    if (menuItem != null)
    {
        ContextMenuStrip menu = menuItem.Owner as ContextMenuStrip;
        if (menu != null)
        {
            // dataElement is your Data for which ContextMenu was opened
            PictureBox dataElement = menu.SourceControl as PictureBox;
        }
    }
}
编辑: 您还可以创建自己的UserControl,并使用它代替数据。在您的示例中,数据中只有PictureBox。如果PictureBox实际上是您的数据对象,您可以这样做:

public class Data : PictureBox
{
    public Data() : base()
    {
        this.Size = new Size(40,40);
        this.BackColor = Color.Red;
    }
}
然后,您的数据对象是控制对象的后代,您可以将ContextMenu绑定到它,甚至您应该能够使用以下代码获得它:

Data dataElement = menu.SourceControl as Data;
void mi_Click(object sender, EventArgs e)
{
    // try to convert your "sender" to a ToolStripItem
    ToolStripItem item = (sender as ToolStripItem);

    if (item != null) 
    {
        // if successful - get the MenuItem's "Parent" -> that should be your "ContextMenu"
        ContextMenuStrip ctxMenu = item.Owner as ContextMenuStrip;

        if(ctxMenu != null)
        {
            // if that's successful, the context menu's "SourceControl"
            // should tell you which control the menu was opened over 
            Control controlThatCausedMenuItemToBeClicked = ctxMenu.SourceControl;
            string controlsName = controlThatCausedMenuItemToBeClicked.Name;
        }
    }
}

我已经有一段时间没有进行任何Winforms编码了,但是您可能可以通过以下代码找到导致单击的控件:

Data dataElement = menu.SourceControl as Data;
void mi_Click(object sender, EventArgs e)
{
    // try to convert your "sender" to a ToolStripItem
    ToolStripItem item = (sender as ToolStripItem);

    if (item != null) 
    {
        // if successful - get the MenuItem's "Parent" -> that should be your "ContextMenu"
        ContextMenuStrip ctxMenu = item.Owner as ContextMenuStrip;

        if(ctxMenu != null)
        {
            // if that's successful, the context menu's "SourceControl"
            // should tell you which control the menu was opened over 
            Control controlThatCausedMenuItemToBeClicked = ctxMenu.SourceControl;
            string controlsName = controlThatCausedMenuItemToBeClicked.Name;
        }
    }
}
更新:@Mesko获得了
ToolStripItem
ContextMenuStrip
的类名,对-我有点生疏了,不再记得那些了-感谢@Mesko更新了我的帖子


但在最后一步,您将返回打开上下文菜单并单击菜单项的控件。这是一个“通用”控件,但您始终可以获取控件的
.Name
,然后根据名称将各种
图片框分开。

我找到了一个解决方案,它与marc_的几乎相同,所以我接受了他的回答

ContextMenu cm = new ContextMenu();
MenuItem mi = new MenuItem()
{
    Text = "click me"
};
mi.Click += new EventHandler(mi_Click);
cm.MenuItems.Add(mi);
cm.Name = "name";


void tsi_Click(object sender, EventArgs e)
{
    ToolStripItem item = (sender as ToolStripItem);
    if (item != null)
    {
        ContextMenuStrip owner = item.Owner as ContextMenuStrip;
        if (owner != null)
        {
             string a = owner.Name;
        }
    }
}

查看Stackoverflow站点右上角的大突出框,其中有一个放大镜和
搜索
文本??只需在此处输入您要搜索的内容,然后按ENTER键即可-这就是您在Stackoverflow上搜索的方式…@marc_s这样做了,但仍然看不到答案。你能推荐一个不同于“[c#]点击事件触发器”的关键字吗?首先,你的“触发器”拼写错误-它有两个
g
-但我同意,要找到这个问题的有用答案并不容易……当你检查
点击事件处理程序中的
发送者时,你会得到什么?请尝试以下操作:
string name=sender.name
-这会提示您单击了哪些图片框/菜单项吗?@marc_s发件人有以下内容:“System.Windows.Forms.MenuItem,items.Count:0,Text:click me”出现错误,提示:无法通过引用转换、装箱转换、取消装箱转换、换行转换或空类型转换将类型“System.Windows.Forms.Control”转换为“WindowsFormsApplication4.Form1.Data”“@BenG:此代码无效,因为您没有将
数据
对象添加到控件集合-只有您的图片框。。。而且,
数据
不是
控件的后代
…True。数据并不像BenG所说的那样属于控制类。您将从该代码中获得PictureBox控件。为了获取数据,您可以将数据对象保存到列表中,并将PictureBox的标记元素设置为该列表中的索引。这样您就可以找到该PictureBox的数据对象。不幸的是,controlsName是一个空字符串