如何确定触发点击事件的位置

时间:2013-12-22 21:03:40

标签: c# click

在Windows窗体上,我有PictureBoxes,每个都有一个StripMenu项。 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
        };
    }

很抱歉,如果已经提出这个问题,但我不知道如何搜索答案。

提前致谢

3 个答案:

答案 0 :(得分:1)

您可以通过以下代码

获取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并使用它而不是数据。在您的示例中,Data中只包含PictureBox。如果PictureBox实际上是您的数据对象,您可以这样做:

public class Data : PictureBox
{
    public Data() : base()
    {
        this.Size = new Size(40,40);
        this.BackColor = Color.Red;
    }
}

然后您的数据对象是Control对象的后代,您可以将ContextMenu绑定到它,甚至您应该能够使用此代码获取它:

Data dataElement = menu.SourceControl as Data;

答案 1 :(得分:1)

自从我进行任何Winforms编码以来已经有一段时间了 - 但您可以通过此代码找出导致点击的控件:

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获得了ToolStripItemContextMenuStrip的类名 - 我有点生疏了,不再了解那些 - 更新了我的发帖,感谢@Mesko。

但是在最后一步,你得到了打开上下文菜单的控件,并点击了菜单项。这是一个“通用”控件,但您始终可以获取控件的.Name,然后根据其名称保持各种PictureBoxes分开。

答案 2 :(得分:0)

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

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