2012-10-21 10 views
5

Mam kilka pól tekstowych w panelu na mój C# Winform. Każdy wiersz polach tekstowych są nazwane tak:Jak manipulować nazwami zmiennych na podstawie wywołującego (przycisku) nadawcy (przycisk #) wywołującego metodę?

TB1 tbNickName1 comboBox1
Tb2 tbNickName2 comboBox2
TB3 tbNickName3 comboBox3

i tak dalej.

Mam przycisk obok każdego z wierszy pól tekstowych. Ale zamiast tego, że przycisk wskazuje na inne zdarzenie dla każdego przycisku, chcę wskazać przycisk tylko zdarzeniu button1_Click i zlecić wykonanie całego przetwarzania. Wiem, jak to zrobić, a wszystkie moje przyciski wskazują na zdarzenie Button1_Click.

Ale muszę być w stanie określić, z którego przycisku został wywołany (co mogę zrobić), ale muszę manipulować nazwami pól tekstowych w wydarzeniu, aby można było przetwarzać na podstawie tego, co wiersz Jestem/button, z którego dzwonię.

Na przykład, jeśli znajduję się w wierszu nr 2, gdzie znajdują się pola tekstowe tb2 tbNickName2 comboBox2, to muszę mieć możliwość poznania tego zdarzenia Button1_Click i automatycznie przypisać wartości tb2 tbNickName2 comboBox2 do zmiennych tmp, których używam. w poniższym przykładzie.

private void button1_Click(object sender, EventArgs e) 
{ 
     Button bt = (Button) sender; //will return 'button1' 

     string tmpEmail = null; 
     string tmpNickName = null; 
     string tmpGroup = null; 

     //I don't want to hard code the tb1.Text value here, I want to have 
     // the namechange based on which (Button) sender it was called from. 

     // For example button1 should assign all the 
     // tb1 tbNickName1 comboBox1 values 

     //If called from button2, then it should assign the 
     //tb2 tbNickName2 comboBox2 values instead 

     //How can I do this so tb1.Text is based off of the button # that I am 
     //calling for example tb(bt).Text would be cool but that does not work. 

     tmpEmail = tb1.Text; //What do I change tb1.Text to based on button #? 

     tmpNickName = tbNickName1.Text; //What do I change tbNickName1.Text to? 

     tmpGroup = comboBox1.Text;//What do I change comboBox1.Text to? 
} 


wiem, że nie wyjaśniłem to bardzo dobrze, ale to najlepsze, co mogę zrobić.

+0

stosowanie może używać CommandArgument-PROPERTY przycisków i oceniają, że w EventHandler. – mboldt

+0

Czy możesz pokazać mi przykład kodu, jak to zrobić? – fraXis

+0

Po napisaniu krótkiego fragmentu kodu jako odpowiedzi. – mboldt

Odpowiedz

1
Button button = sender as Button; 
string buttonIndex = button.Name.Substring(6); 
string tempEmail = (this.Controls["tb" + buttonIndex] as TextBox).Text; 
string tmpNickName = (this.Controls["tbNickName" + buttonIndex] as TextBox).Text; 
string tmpGroup = (this.Controls["comboBox" + buttonIndex] as ComboBox).Text; 
+0

string tempEmail = (this.Controls ["tb" + buttonIndex] jako TextBox) .Text; powoduje błąd "Obiekt nie odwołuje się do instancji obiektu". – fraXis

+0

Więc TextBox z nazwą tb + buttonIndex nie istnieje w twoim WinForm – Denis

+0

Wyobraziłem błąd. Zmieniłem wiersz kodu tak, aby zawierał nazwę mojego panelu i teraz działa dobrze: string tempEmail = (this.panel1.Controls ["tb" + buttonIndex] jako TextBox) .Text; – fraXis

0

Na guziki, dodasz CommandArgument-obiekt, który mógłby wyglądać następująco

bt1.CommandArgument = "1"; 
bt2.CommandArgument = "2"; 

W swojej EventHandler, czytasz CommandArgument i działać odpowiednio

private void button1_Click(object sender, EventArgs e) 
    { 
     Button bt = (Button) sender; 
     if(bt.CommandArgument == "1") { 
      // bt1 was clicked, handle stuff accordingly 
     } else if(bt.CommandArgument == "2") { 
      // bt2 was clicked.. 
     } else { 
      //handle rest of possible cases 
     } 
    } 

To tylko pseudo kod ale Myślę, że widzisz, dokąd to zmierza. Należy jednak pamiętać, że nazwy zmiennych są dalekie od optymalnych. Wybierz nazwy zmiennych i elementów sterujących, które dają ci jakąkolwiek informację, a nie tylko nazywanie ich liczbami. Bardzo ci to pomoże, jeśli spojrzysz na kod później i spróbujesz go zrozumieć. Podobnie jak to, spróbuj również znaleźć sensowne wartości CommanArgument.

+0

Rozumiem, co masz na myśli, ale mam tyle kodu, który jest oparty na każdym wierszu pól tekstowych, które chcę przypisać do moich zmiennych tymczasowych. Chcę uniknąć posiadania całego tego duplikatu pomiędzy różnymi instrukcjami if/else. Chcę mieć jeden zestaw kodu, który przypisuje pola tekstowe do zmiennych tymczasowych na podstawie tego, który przycisk # wywołuje zdarzenie. – fraXis

+0

Jeśli kod, który powinien być wykonany dla każdego przypadku, jest zawsze taki sam, a następnie po prostu umieść go w innej metodzie, ustaw zmienne temp zgodnie z CommandArgument i przekaż te zmienne temp do metody, która wykonuje twój rzeczywisty kod. – mboldt

+0

Większość kodu jest taka sama, z wyjątkiem nazw zmiennych, które ulegną zmianie na podstawie pól tekstowych, których potrzebuję do przypisania wartości. Wciąż jest wiele powtórzeń kodu w wielu metodach i chcę spróbować czegoś bardziej wydajnego i łatwiejszego w utrzymaniu. – fraXis

1

można zrobić coś takiego (iteracji po kontroli w panelu):

//Get the number of the button control (last digit of the name) 
    string strNum = bt.Name.Substring(bt.Name.Lenght -2); 
    foreach(Control ctrl in myPanel.Controls) 
    { 
     if(ctrl is ComboBox) { 
      if(ctrl.Name.EndsWith(strNum)) { 
      //Do Something with your found ComboBox ... 
      } 
     } 
    } 

kod nie testowane, ale powinien dać wyobrażenie ...

-1

Po pierwsze, na własną rękę, nasz i każdy, kto kiedykolwiek patrzy na twoje kody, zmień konwencję nazewnictwa.

Jeśli chodzi o rozwiązanie, proponuję umieszczenie odnośników do pól wyboru i pól tekstowych w słowniku podczas ich konstruowania. Niech przyciski zawierają klucz użyty w ich CommandArgument. Teraz możesz odzyskać wiersz, uzyskując dostęp do słownika.

Na przykład, w konstruktorze, ty chcesz dodać coś jak ten

_rowDictionary = new Dictionary<string, Row> { 
    { "identifier of first line", new Row { descriptiveNameOfFirstTextBox, descriptiveNameOfFirstTextBox, descriptiveNameOfButton } }, 
    // ... 
}; 
descriptiveNameOfButton.CommandArgument = "identifier of first line"; 

Następnie w Twojej obsługi zdarzeń

Tutaj użyłem niektóre klasy kontenera . Można od może nie trzeba go

class Row { 
    TextBox textBoxForInputOfA { get; set; } 
    TextBox textBoxForInputOfB { get; set; } 
    Button buttonForDoingWhatItDoes { get; set; } 
} 
Powiązane problemy