2013-08-15 2 views
2

Мне было трудно выяснить, как искать/фразы, что я хочу достичь. Я смотрю, есть ли более безопасный/более умный способ достичь следующего примера.Дифференциация между несколькими объектами, прикрепленными к одному и тому же обработчику событий

Допустим, у меня есть 3 кнопки с названиями:

btnOne
btnTwo
btnThree

Цель каждой кнопки, чтобы написать уникальную строку в какой-то текстовое поле при нажатии. Поскольку все три кнопки выполняют очень похожее действие, кажется логичным создать один обработчик событий для всех трех, но что будет разумным способом для разграничения между тремя кнопками, чтобы правильное текстовое поле могло получить правильную строку? Мне не нравится текущий путь я собираюсь об этом:

псевдо, псевдо код:

private void Clicked(object sender, EventArgs e) 
{ 
    string buttonName = (sender as Button).Name; 
    switch(buttonName) 
    { 
     case "btnOne": 
      tbOne.Text = "This text is from button one"; 
      break; 
     case "btnTwo": 
      tbTwo.Text = "This is some different text"; 
      break; 
     case "btnThree": 
      tbThree.Text = "Button three text"; 
      break; 
    } 
} 

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

private void AfterButtonClicked(Textbox tb, string text) 
{ 
    tb.Text = text; 
} 
+0

Является ли это WinForms? Если это так, все элементы управления имеют свойство 'tag' типа' object', чтобы вы могли вставлять все, что хотите. Это может быть так же просто, как установить свойство «tag» на каждой кнопке, и когда он щелкнут, получите значение от него и выведите его. – Justin

ответ

1

В вашем случае повторно код установка некоторых TextBox в Text собственности на некоторых строки. Лично я не вижу преимущества написания одного обработчика событий в том, как вы продемонстрировали за действие, которое вы продемонстрировали. ИМХО усложняет код, а не упрощает его.

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

В зависимости от действующего приложения и кода внутри обработчика это наблюдение может быть или не быть действительным.


Однако, один из способов вы могли рефакторинг это было бы:

Dictionary<Button, TextBox> buttonTextboxMap = new Dictionary<Button, TextBox> 
{ 
    {btnOne, tbOne}, 
    {btnTwo, tbTwo}, 
    {btnThree, tbThree} 
}; 

Dictionary<Button, string> buttonStringMap = new Dictionary<Button, string> 
{ 
    {btnOne, "This text is from button one"}, 
    {btnTwo, "This is some different text"}, 
    {btnThree, "Button three text"} 
}; 

void Clicked(object sender, EventArgs e) 
{ 
    Button btn = (Button)sender; 

    buttonTextboxMap[btn].Text = buttonStringMap[btn]; 
} 

Второй способ будет использовать Tag свойство каждой кнопки. Мне это нравится, потому что он хранит все, заключенное в самой кнопке.Однако падение - это только одно свойство Tag, и вам не гарантировано, что он содержит соответствующую информацию. (Можно также создать подкласс Button провести надлежащую информацию, но я предполагаю, что это зависит от того, насколько многократного использования вы после и сколько раз вы будете использовать эту конкретную кнопку):

class TextBoxAndString 
{ 
    public TextBox tb {get; set;} 
    public String s {get; set;} 
} 

.ctor() //the form's constructor 
{ 
    btnOne.Tag = new TextBoxAndString {tb = tbOne, s = "This text is from button one"}; 
    btnTwo.Tag = new TextBoxAndString {tb = tbTwo, s = "This is some different text"}; 
    btnThree.Tag = new TextBoxAndString {tb = tbThree, s = "Button three text"}; 
} 

void Clicked(object sender, EventArgs e) 
{ 
    Button btn = (Button)sender; 
    TextBoxAndString tbs = (TextBoxAndString)btn.Tag; 

    tbs.tb.Text = tbs.s; 
} 
+0

Какой-то гений, чтобы использовать свойство тега :) – Justin

+0

Предположим, что было 100 кнопок, и все они должны были сделать что-то подобное, но требовали большей уникальности, чем текстовое поле и строку. По вашему решению я мог бы создать класс, содержащий все уникальные параметры каждой кнопки, список <* новый класс здесь *>, а затем общий обработчик событий, который просматривал список для класса, который соответствует кнопке (с сохранением рефакторинга). Это также отличное решение – Doug

+0

@ Justin Да, мне нравится свойство тега (просто посмотрел ваш комментарий на вопрос :)). Единственный недостаток - это не безопасный тип, но обычно это не проблема для хранения простой «дополнительной информации» –

0

Это такой простой случай, я думаю, я бы просто оставить их в своих собственных обработчиков событий для простоты.

Если вы хотите иметь одно событие, хотя, вы можете проверить с помощью sender:

private void Clicked(object sender, EventArgs e) 
{ 
    if (sender is btnOne) 
     tbOne.Text = "This text is from button one"; 
    else if (sender is btnTwo) 
     tbTwo.Text = "This is some different text"; 
    else if (sender is btnThree) 
     tbThree.Text = "Button three text"; 
} 

По крайней мере, если переименовать кнопки, ваша программа не компилируется, и вы будете приходить сюда Исправить это.

У вас есть это сейчас, если вы переименуете «btnOne» в «btn1», текст в tbOne не сможет обновиться, и вы можете его не заметить.

+0

Выше был только пример. Может быть, есть 100 кнопок, которые делают что-то сложное, подобное достаточно, чтобы гарантировать один обработчик событий, но все же требуя уникальных методов в зависимости от того, какая кнопка была нажата. Оператор «is» выглядит как более умный способ обойти это точно – Doug

Смежные вопросы