1

I am creating a C# application which fetches data from a database, and dynamically creates 5 textBoxes and one button in a single row.

The number of rows present in the database equals the number of rows of textBoxes and buttons that are created.

I could successfully create the rows of textBoxes and buttons, the textBoxes are even capable of displaying data that is being fetched from the database.

My trouble however is that the button that is generated, does nothing when clicked, now that is not unexpected since i haven't created a handler to handle the click event. But i am confused on how to dynamically create the click even handler for the buttons that are again generated dynamically.

Below is the code sample that generated the textBoxes and buttons.

for (int i = 3; i <= count; i++)
{
    com.Parameters[0].Value = i;
    using (SqlCeDataReader rd = com.ExecuteReader())
    if (rd.Read())
    {
        pname = (rd["pname"].ToString());
        cname = (rd["cname"].ToString());
        budget = (rd["budget"].ToString());
        advance = (rd["advance"].ToString());
        ddate = (rd["ddate"].ToString());

        TextBox tobj = new TextBox();
        tobj.Location = new Point(10, (40 + ((i - 2) * 20)));
        tobj.Tag = 1;
        tobj.Text = pname;
        tobj.AutoSize = false;
        tobj.Width = 150;
        tobj.ReadOnly = true;
        this.Controls.Add(tobj);

        TextBox tobj1 = new TextBox();
        tobj1.Location = new Point(160, (40 + ((i - 2) * 20)));
        tobj1.Tag = 2;
        tobj1.Text = cname;
        tobj1.AutoSize = false;
        tobj1.Width = 150;
        tobj1.ReadOnly = true;
        this.Controls.Add(tobj1);

        TextBox tobj2 = new TextBox();
        tobj2.Location = new Point(310, (40 + ((i - 2) * 20)));
        tobj2.Tag = 3;
        tobj2.Text = budget;
        tobj2.AutoSize = false;
        tobj2.Width = 100;
        tobj2.ReadOnly = true;
        this.Controls.Add(tobj2);

        TextBox tobj3 = new TextBox();
        tobj3.Location = new Point(410, (40 + ((i - 2) * 20)));
        tobj3.Tag = 4;
        tobj3.Text = advance;
        tobj3.AutoSize = false;
        tobj3.Width = 100;
        tobj3.ReadOnly = true;
        this.Controls.Add(tobj3);

        TextBox tobj4 = new TextBox();
        tobj4.Location = new Point(510, (40 + ((i - 2) * 20)));
        tobj4.Tag = 5;
        tobj4.Text = ddate;
        tobj4.AutoSize = false;
        tobj4.Width = 100;
        tobj4.ReadOnly = true;

        int due = 0;
        due = int.Parse(ddate);
        if (due < 5)
        {
             tobj4.BackColor = System.Drawing.Color.Red;
        }

        this.Controls.Add(tobj4);

        Button button = new Button();
        button.Left = 620;
        button.Tag = i;
        button.Height = 20;
        button.Text = "Details";
        button.Top = (40 + ((i - 2) * 20));
        this.Controls.Add(button);  
    }
}

Please give me some ideas on how to generate the click event handler.

3
  • 1
    Why is this question tagged sql-server? Commented Jan 7, 2013 at 16:36
  • because the app is fetching data from the sql server, and i had run into a similar problem with controls which later turned out to be caused due to an exception being thrown due a faulty sql query. Commented Jan 7, 2013 at 16:38
  • @RickRoy how is button click related to sql server? Commented Jan 7, 2013 at 16:42

2 Answers 2

5

Answer part:

Add this:

button.Tag = i;
button.Click += handleTheClick;

...

private void handleTheClick(object sender, EventArgs e){
    Button btn = sender as Button;
    int row = (int)btn.Tag;
}

Un-answer:

You should reconsider your design. Including coordinates in your data processing code is a really bad idea in 2013, try using ListView, ListBox, GridView or better - switch to WPF.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, this works. I will improve my design @Sten Petrov but i am new to C# so just trying it out. Thanks for the help :)
@RickRoy I understand you're new, no better time to start learning the "new" thing instead of learning historic tech. You wouldn't start learning BASIC or Fortran, would you?
4

You need to subscribe to the Click events:

button.Click += ... some event handler ...

You can use a method for the handler:

button.Click += MyEventHandlerMethod;

// put this method somewhere in your Form class
void MyEventHandlerMethod( object sender, EventArgs args )
{
  ...

Or even a lambda:

button.Click += ( s, e ) => HandleClick( ... any parameters here ... );

// put this method somewhere in your Form class
void HandleClick( ... required parameters ... )
{
  ...

As a hint, you can look in the .designer.cs file of a normal Form to see how things are done.

2 Comments

tobj here refers to textbox-es, they don't have Click methods. Also the "lambda" isn't really a lambda if it just redirects the handling elsewhere, is it. The benefit of the lambda is you could keep the row object alive (although it would be a memory leak, so use with caution)
@StenPetrov oops - changed to button now. The advantage of using a lambda is that you can close over local variables and pass them as parameters. Also, the handler method doesn't have to have an EventHandler signature.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.