C # Windows Form: Looping gennem Dynamically created TextBoxes og tjekker for at se, om tekst er ændret

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg forsøger at oprette en grafisk SQL editor af slags - men jeg kan ikke lide billedets visuelle og forsøger at tilføje mere interaktivitet (træk/slip osv.).


Jeg har gået igennem og lavet paneler baseret på hver post og tilføjede tekstbokse til hvert panel baseret på hver post fra mit bord. Hvad jeg nu sidder fast på, er begrebet looping gennem dynamisk oprettede kontroller og kontrol af deres tilstand eller interagerer med dem.


Lad mig vide, hvis du ser problemer med, hvordan jeg strukturerer dette.


Min kode er som følger:


Kode, der genererer panelerne:


  private void comboBox1\_SelectedIndexChanged\_1(object sender, EventArgs e)
    {
        groupBox1.Controls.Clear();
        string pDBString = null;
        SqlConnection cnn;
        pDBString = "Data Source=localhost\" + Form1.host + ";Initial Catalog=" + Form1.db + ";Integrated Security=SSPI;";
        cnn = new SqlConnection(pDBString);
        string sqlForProps = "select * from PROPS where user\_id\_txt ='" + comboBox1.SelectedItem.ToString() + "'";
        try
        {
            using (cnn)
            {
                cnn.Open();
                SqlCommand cmd = new SqlCommand(sqlForProps, cnn);
                SqlDataReader sqlReader = cmd.ExecuteReader();

                int x = 0;
                int count = 0;
                while (sqlReader.Read())
                {
                    Panel panel = new System.Windows.Forms.Panel();
                    panel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
                    x += 30;
                    panel.Location = new System.Drawing.Point(3, x);
                    panel.Name = "panel" + count;
                    panel.Size = new System.Drawing.Size(519, 30);
                    panel.TabIndex = 3;
                    PropsPanels.Add(panel);
                    groupBox1.Controls.Add(panel);

                    TextBox textbox = new System.Windows.Forms.TextBox();
                    panel.Controls.Add(textbox);
                    textbox.Location = new System.Drawing.Point(1, 3);
                    textbox.Name = "textBox" + count;
                    textbox.Size = new System.Drawing.Size(100, 20);
                    textbox.TabIndex = 4;
                    textbox.Text = sqlReader["USER\_ID\_TXT"].ToString();

                    TextBox textboxAM = new System.Windows.Forms.TextBox();
                        panel.Controls.Add(textboxAM);
                        textboxAM.Location = new System.Drawing.Point(126, 3);
                        textboxAM.Name = "textBoxAM" + count;
                        textboxAM.Size = new System.Drawing.Size(100, 20);
                        textboxAM.TabIndex = 4;
                        textboxAM.Text = sqlReader["PROP\_TXT"].ToString();

                    TextBox textboxAMSet = new System.Windows.Forms.TextBox();
                        panel.Controls.Add(textboxAMSet);
                        textboxAMSet.Location = new System.Drawing.Point(232, 3);
                        textboxAMSet.Name = "textBoxAM" + count;
                        textboxAMSet.Size = new System.Drawing.Size(100, 20);
                        textboxAMSet.TabIndex = 4;
                        textboxAMSet.Text = sqlReader["VAL\_TXT"].ToString();
                    count++;
                }
                sqlReader.Close();
                cnn.Close();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Can not open connection !");
        }

    }


Koden, der antages at kontrollere panelerne:


        public AMMain()
    {

        InitializeComponent();
        string pDBString = null;
        SqlConnection cnn;
        pDBString = "Data Source=US7-AHACKETT\SQLEXPRESS;Initial Catalog=OrchestroConfigurationDB;Integrated Security=SSPI;";
        MessageBox.Show(pDBString);
        cnn = new SqlConnection(pDBString);
        try
        {
            using (cnn)
            {
                SqlCommand sqlForUserList = new SqlCommand("select UserName from users a join Company b on a.CompanyID = b.CompanyID where CompanyCode='" + Form1.company + "'", cnn);
                cnn.Open();
                MessageBox.Show("Connection Open !");
                SqlDataReader sqlReader = sqlForUserList.ExecuteReader();
                while (sqlReader.Read())
                {
                    comboBox1.Items.Add(sqlReader["UserName"].ToString());
                }
                sqlReader.Close();
                cnn.Close();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Can not open connection !");
        }

        foreach (Panel p in PropsPanels)
        {
            foreach (Control c in p.Controls)
            {
                if(c is TextBox)
                {
                    object sender = new object();
                    EventArgs e = new EventArgs();
                    if(c.TextChanged()??????)
                    {
                     //DOSOMETHING   
                    }
                }
            }
        }
    }


For eksempel: hvis jeg ønskede at kontrollere, om tekst ændret til en tekstboks, som jeg skrev på formularen, ville jeg gøre det:


        private void textBox1\_TextChanged(object sender, EventArgs e)
    {

    }


Så jeg gætter på, at jeg ikke kan lægge hovedet rundt om, hvordan jeg vil tjekke dette på run-time siden jeg laver tekstboksene på kørselstidspunktet.


Tak for enhver hjælp!

Bedste reference



  For eksempel: hvis jeg ønskede at kontrollere om tekst ændret til en tekstboks, at jeg
  læg på formularen ville jeg gøre det:


private void textBox1\_TextChanged(object sender, EventArgs e)
{

}

  
  Så jeg antager, at jeg ikke kan lægge hovedet rundt om, hvordan jeg vil tjekke dette på
  run-time siden jeg skaber tekstboksene på kørselstidspunktet.



Du gør det samme!


Opret en metode til at håndtere begivenheden først:


private void TextBoxTextChanged(object sender, EventArgs e) {
    // you can use the sender argument to check exactly which text box's text changed
}


Når du initialiserer din formular, gør du det her:


textbox.TextChanged += TextBoxTextChanged;
textboxAM.TextChanged += TextBoxTextChanged;
textboxAMSet.TextChanged += TextBoxTextChanged;

Andre referencer 1


Du kan gøre det på samme måde som om du havde tabt tekstbokse på plads manuelt. Du skal bare abonnere på hver ny TextBox 's TextChanged begivenhed.


var x = new TextBox();

x.TextChanged += textBox1\_TextChanged;


I ældre versioner af .Net kan du muligvis angive delegeret. Se MSDN om emnet for mere information. [14]

Andre referencer 2


Du skal registrere dig på delegationen TextChanged, når du opretter kontrollerne.


TextBox textbox = new System.Windows.Forms.TextBox();
panel.Controls.Add(textbox);
textbox.Location = new System.Drawing.Point(1, 3);
textbox.Name = "textBox" + count;
textbox.TextChanged += TextBox\_TextChanged


Brug derefter sender -parameteren til hændelseshåndteringen til at kaste til forekomsten af ​​den kontrol, der fyrede begivenheden.


  private void(object sender, EventArgs e)
    {
        //get name of textbox
        var tb = (TextBox) sender;
        // do whatever with text box
    }