2016-01-10 7 views
0

Прежде всего, я хотел бы извиниться за недостаток знаний, но я новичок в C#, и мне не хватает некоторых основных принципов.Как продлить функцию MouseEventHandler

Вот мой текущий сценарий: В моем сценарии я создаю что-то вроде шахматного столе pictureboxes. Они размещены внутри элемента управления «Панель» в Winform форма - панель прокручивается! Каждый квадрат изображения имеет уникальное имя, например pbR1_C1, сгенерированное в конструкторе.

R - означает Row на столе

С - Стойки для колонны на столе

Все сделано во время выполнения, так как размер шахматной регистрации загружается после запуска программы. Используемые объекты выглядеть следующим образом:

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

Благодарим вас. И, пожалуйста, объясните это как можно проще, для манекена. :-)

+1

Я только отредактировал мой ответ, чтобы показать вам, как интегрировать событие в свой собственный класс – Shnugo

ответ

2

Вы можете попробовать это так:

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

После обсуждения с Якуб 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(); 
    } 

} 

Снаружи вы можете отреагировать на это событие, а не на событие ClickBox PictureBox. «Отправитель» будет непосредственным экземпляром вашего собственного класса.

Если вы хотите, вы можете даже определить собственный EventArgs-класс, чтобы пройти какие-либо параметры вы хотите ...

1

В качестве прямого ответа на свой вопрос, вы можете сделать что-то вроде этого:

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

Вы можете передать любой параметр, который вы хотите.

Это полезно, если вы хотите больше контекста, чем только PictureBox, который был нажат, поскольку этот объект может быть доступен с помощью параметра sender. Например, вы можете получить доступ к соответствующему ptFcElement.

+0

Этот подход вполне Hacky ... Вы Underrun принципов событий ... Во всяком случае не было бы лучше конструкций. Может быть, полученный PictureBox, включая все другие данные или определенный пользователем класс, бросает свое собственное событие. То, что вы предлагаете, как-то - ухм - красиво уродливо :-) – Shnugo

+0

@ Шнуго, ты прав :). Я просто даю ОП прямой ответ на вопрос. Я не уверен, есть ли у нас достаточно контекста, чтобы предложить лучший дизайн. –

+0

Так что я мог бы использовать какой-то волшебный трюк, называемый лямбда-выражением. Хорошо, спасибо вам, я постараюсь заставить его работать. :-) На данный момент я получаю ошибку, потому что в моем примере я создаю объект с помощью «new MouseEventHandler (MouseButton_Click)» В новой идее я не использую «новый» оператор, поэтому мне придется подумать что нибудь. В любом случае, большое вам спасибо! :-) –

0

В основном вы пытаетесь определить, управление которым была нажата? Надеюсь, это то, о чем вы просите. Параметр отправителя содержит ваш элемент управления. Например:

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

Нет, это не так. Я пытаюсь определить, какой из них был выбран. Есть десятки картинок, и я не могу определить, какой из них я нажал. –

+0

Ну, ящик для фотографий - это элемент управления. –