如何扩展 MouseEventHandler 函数

How to extend MouseEventHandler function

首先,我想为我的知识不足道歉,但我是 C# 的新手,我缺少一些基本原理。

这是我目前的情况: 在我的场景中,我创建了类似 pictureboxes 的国际象棋桌。它们以 Winform 形式放置在控件 "Panel" 内 - 面板是 可滚动 ! 每个图片框都有唯一的名称,例如在构造函数中生成的 pbR1_C1

R - 代表桌子上的行

C - 代表 Column on desk

所有都是在运行时完成的,因为棋盘大小是在程序启动后加载的。使用的对象如下所示:

/* Simple preview of object with public variables - just for preview  */

public class ptFcElement                    
{
    public string stName;                   /* "pbR1_C1", "pbR1_C2" */
    public int iRow;                        /* 1                    */
    public int iColumn;                     /* 4                    */
    public PictureBox pbPictureBox;         /* using System.Drawing;*/                                          

    public ptFcElement()                                                               
    {
        stName = sGenerateName();
    }

}

然后我为每个图片框分配事件处理程序

ptFcElementTemp.pbPictureBox.MouseClick += new MouseEventHandler(MouseButton_Click);

此时我可以识别我按下了某个图片框,但我不知道是哪个。

问题如下: 由于面板是可滚动的——我不能简单地识别按下的图片框——它总是调用相同的函数。

void MouseButton_Click(object sender, MouseEventArgs e)
{
    //Do some stuff....
    //In case panel is not scrollable, 
    //I can identify pressed picture box by coordinates of mouse click.  
    //But if panel is scrollable, I am screwed.
} 

想要的想法:

有没有可能扩展MouseEventHandler事件函数?我知道简单的 类 很容易扩展,但我不确定如何使用事件函数。

ptFcElementTemp.pbPictureBox.MouseClick += 
        new MouseEventHandler(MouseButton_Click, "pbR1_C1");

void MouseButton_Click(object sender, MouseEventArgs e, string sUniqueName)
{
    //Here I am able to identify pressed bisturebox by sUniqueName
     if (sUniqueName == "pbR1_C1")
     {
         //do something
     }

     if (sUniqueName == "pbR2_C3")
     {
         //do something different
     }
} 

谢谢,回见。 并且请尽可能简单地解释它,以供假人使用。 :-)

作为对您问题的直接回答,您可以这样做:

ptFcElementTemp.pbPictureBox.MouseClick +=
    (object sndr, MouseEventArgs m_args)
        => MouseButton_Click(sndr, m_args, "pbR1_C1");

您可以传递任何您想要的参数。

如果您想要更多上下文而不只是单击的 PictureBox,这将很有帮助,因为可以使用 sender 参数访问该对象。例如,您可能想要访问相应的 ptFcElement.

你可以这样试试:

void MouseButton_Click(object sender, MouseEventArgs e)
{
    var pb = sender as PictureBox;
    if(pb!=null){
        //Do something with the instance the PictureBox which fired the event
    }
} 

在与 Yacoub Massad 讨论后,我想建议您进行以下改进:

声明您自己的事件,单击 PictureBox 时将触发该事件。

public class ptFcElement {
    public string stName;                   /* "pbR1_C1", "pbR1_C2" */
    public int iRow;                        /* 1                    */
    public int iColumn;                     /* 4                    */
    public PictureBox pbPictureBox;         /* using System.Drawing;*/

    public event EventHandler PictureBoxWasClicked;
    protected virtual void OnPictureBoxWasClicked(){
        if (this.PictureBoxWasClicked != null)
            this.PictureBoxWasClicked(this, new EventArgs());
    }

    public ptFcElement() {
        stName = sGenerateName();
        this.pbPictureBox.Click += pbPictureBox_Click;
    }

    private void pbPictureBox_Click(object sender, EventArgs e) {
        this.OnPictureBoxWasClicked();
    }

}

您可以在外面对此事件而不是 PictureBox 做出反应 Click-event。 "sender" 将直接成为您自己的 class 的实例。

如果你愿意,你甚至可以定义一个自己的 EventArgs-class 来传递你喜欢的任何参数...

基本上您是在尝试确定单击了哪个控件?我希望这就是你所要求的。 sender 参数包含您的控件。 例如:

if (sender==ptFcElementTemp.pbPictureBox){
//Do stuff
}
else if(sender==ptFcElementTemp.otherControl){
//Do other stuff
}