Как создать делегата для прослушивания всех текстовых полей в форме - PullRequest
3 голосов
/ 29 февраля 2012

Я изучаю обработчики событий и делегатов.У меня есть одна форма с 4 текстовыми полями и списком.Я хотел бы иметь делегата, который прослушивает изменения текстового поля для ЛЮБОГО из 4 блоков.Метод, связанный с делегатом, будет просто методом, который принимает текстовое значение измененного текстового поля и добавляет его в качестве нового элемента списка.Мой вопрос заключается в том, как написать делегат для прослушивания всех текстовых полей, и когда я вызываю функцию для добавления элемента списка, как я могу передать объект текстового поля, поскольку я не буду точно знать, какой из них поднялсобытие?Будет ли это содержаться в EventArgs e?

Вместо того, чтобы использовать несколько обработчиков событий:

this.textBo1.TextChanged += txt_TextChanged;
this.textBo2.TextChanged += txt_TextChanged;
this.textBo3.TextChanged += txt_TextChanged;
this.textBo4.TextChanged += txt_TextChanged;

Мне бы хотелось что-то вроде:

public delegate ListenToTextBoxes(object sender, EventArgs e);

не имеет смысла, так как я новичок в делегатах, но мне кажется разумным, что я должен иметь возможность заставить одного делегата прослушивать элементы управления текстовым полем в целом, а затем, когда он вызывает событие, я разыскиваю отправителя объекта и получаютекстовое поле текст.Но как мне создать делегата, чтобы он слушал ТОЛЬКО текстовые поля или другие типы элементов управления?

Ответы [ 3 ]

6 голосов
/ 29 февраля 2012

Как насчет этого?

// form constructor
public MyForm()
{
   InitializeComponent();
   this.textBo1.TextChanged += txt_TextChanged;
   this.textBo2.TextChanged += txt_TextChanged;
   this.textBo3.TextChanged += txt_TextChanged;
   this.textBo4.TextChanged += txt_TextChanged;
}

// event handler
void txt_TextChanged(object sender, EventArgs e)
{
   var textBox = (TextBox)sender;
   this.myList.Add(textBox.Text);
}

РЕДАКТИРОВАТЬ:
(согласно обновлению вопроса)

На самом деле предыдущий код может быть легко изменен для создания одного делегата и передачи его всем текстовым полям, но он не меняется слишком сильно (все еще есть четыре подписки на события):

public MyForm()
{
    InitializeComponent();

    // EventHandler is defined as:
    // delegate void EventHandler(object sender, EventArgs e)
    // so its signature is equal to your delegate:
    // delegate void ListenToTextBoxes(object sender, EventArgs e);
    // Hence, if you receive that delegate from somewhere out, you can pass it
    // to TextChange events
    var myDelegate = new EventHandler(txt_TextChanged);

    this.textBox1.TextChanged += myDelegate;
    this.textBox2.TextChanged += myDelegate;
    this.textBox3.TextChanged += myDelegate;
    this.textBox4.TextChanged += myDelegate;
}

Проблема в том, что вам нужно подписать событие TextChanged для каждого элемента управления TextBox, волшебного способа , который бы говорил «зарегистрировать все события TextBox.TextChange для этого делегата», нет.
Но если вы уверены, что все текстовые поля, которые вы хотите зарегистрировать, являются дочерними элементами этого элемента управления, вы можете использовать цикл, например, :

public MyForm()
{
    InitializeComponent();
    var myDelegate = new EventHandler(txt_TextChanged);
    foreach (var ctrl in this.Controls)
    {
        var txtBox = ctrl as TextBox;
        if (txtBox != null)
            txtBox.TextChanged += myDelegate;
    }
}
2 голосов
/ 29 февраля 2012

Используйте «отправитель». Вот пример:

textBox1.Click += AllTextBoxes_Click;
textBox2.Click += AllTextBoxes_Click;

void AllTextBoxes_Click(object sender, EventArgs e)
{
    TextBox tb = sender as TextBox;
    tb.Text = "Clicked here";
}

В связи с обновленным вопросом:

public Form1()
{
    InitializeComponent();
    Listen(this);
}    

void Listen(Control ctrl)
{
    foreach (Control ctrl2 in ctrl.Controls)
    {
        if (ctrl2 is TextBox) (ctrl2 as TextBox).TextChanged += tb_TextChanged;
        foreach (Control ctrl3 in ctrl2.Controls) Listen(ctrl3);
    }
}

void tb_TextChanged(object sender, EventArgs e)
{
    //Do things...
}
0 голосов
/ 29 февраля 2012

Вы можете интуитивно понять другие ответы, что sender - это объект, вызывающий событие (одно из ваших четырех текстовых полей, как только событие присоединено к Click), однако для более подробного объяснения определения отправителя я бы предложить КАК: Определить отправителя события без использования свойства Control.Name

...