5

我的 C# Winform 面板中有一堆文本框。每行文本框的命名如下:

tb1 tbNickName1 组合框
1 tb2 tbNickName2 组合框2
tb3 tbNickName3 组合框3

等等。

我在每一行文本框旁边都有一个按钮。但不是让按钮指向每个按钮的不同事件,我想将按钮指向 button1_Click 事件并让它在那里完成所有处理。我知道怎么做,我所有的按钮都指向 button1_Click 事件。

但是我需要能够确定从哪个按钮调用它(我可以这样做),但是我需要操纵事件中文本框的名称,以便我可以根据我所在的行进行处理/我从中调用的按钮。

例如,如果我在 tb2 tbNickName2 comboBox2 文本框所在的第 2 行,那么我需要能够让 button1_Click 事件知道这一点并自动将 tb2 tbNickName2 comboBox2 值分配给我在下面的示例中使用的 tmp 变量.

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


我知道我没有很好地解释这一点,但这是我能做的最好的。

4

4 回答 4

1

您可以执行以下操作(迭代面板中的控件):

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

代码未经测试,但应该给你一个想法......

于 2012-10-21T08:18:15.977 回答
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;
于 2012-10-21T08:27:37.103 回答
0

在按钮上,添加 CommandArgument-Property,它看起来像这样

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

在您的 EventHandler 中,您阅读 CommandArgument 并采取相应措施

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

这只是伪代码,但我想你可以看到这是怎么回事。但是请记住,您的变量命名远非最佳。为您的变量和控件选择名称,这些名称可以为您提供任何类型的信息,而不仅仅是用数字命名它们。如果您稍后查看代码并尝试理解它,那将对您有很大帮助。就像这样,也尝试找到有意义的 CommanArgument-values。

于 2012-10-21T08:15:42.307 回答
-1

首先,为了您自己、我们以及其他任何查看您的代码的人,请更改您的命名约定。

至于解决方案,我建议您在构建复选框和文本框时将它们的引用放入字典中。使按钮包含您在其CommandArgument. 现在您可以通过访问字典来检索该行。

例如,在您的构造函数中,您将添加类似这样的内容

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

然后,在您的事件处理程序中

Button senderButton = (Button) sender;
Row r = _rowDictionary[senderButton.CommandArgument];

在这里,我使用了一些容器类Row。你可能不需要它

class Row {
    TextBox textBoxForInputOfA { get; set; }
    TextBox textBoxForInputOfB { get; set; }
    Button buttonForDoingWhatItDoes { get; set; }
}
于 2012-10-21T08:21:05.270 回答