Search code examples
c#winformsmouseeventeventhandlerextending

How to extend MouseEventHandler function


first, I would like to apologize for my lack of knowledge, but I am new in C# and I am missing some basic principles.

Here is my current scenario: In my scenario I create something like chess desk of pictureboxes. They are placed inside of control "Panel" in Winform form - panel is scrollable! Each picture box has unique name like pbR1_C1 generated in constructor.

R - stands for Row on desk

C - Stands for Column on desk

All is made during runtime since the chess desk size is loaded after program starts. Used objects look like this:

/* 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();
    }

}

Then I assign event handler for each picture box

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

At this point I am able to identify that I have pressed some picture box, but I don't know which one.

Here is the question: Since panel is scrollable - I can not simple identify pressed picture box - it always calls the same function.

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

Desired idea:

Is there any possibility to extend MouseEventHandler event function? I know that simple classes are easily to extend, but I am not sure how to work with event functions.

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

Thank you, see you. And please, explain it as easy as possible, for dummy. :-)


Solution

  • You could try it like this:

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

    After discussion with Yacoub Massad I want to suggest you following enhancement:

    Declare your own event, which you fire when the PictureBox is clicked.

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

    Outside you can react on this event instead of the PictureBox' Click-event. The "sender" will be the instance of your own class directly.

    If you want you could even define an own EventArgs-class to pass what ever parameters you like...