Hi, this is my first post, so any help or advicing is welcome.

I have a form in which i want to show records from a database and create buttons for each record, the problem is that i need to point the buttons in diferent locations inside the form based in the last button position, this is my starting code:

MySqlCommand comm = new MySqlCommand("SELECT * FROM sah_rooms WHERE hotel_id = 1  ", clsMySQL.con);
            try
            {
                MySqlDataReader reader = comm.ExecuteReader();
                while (reader.Read())
                {

                    foreach (var element in reader)
                    {
                        
                        
                        btnAdd.Size = new System.Drawing.Size(150, 90);
                        if (reader["maintenance"].ToString() == "1")
                        {
                            btnAdd.BackColor = Color.CadetBlue;
                        }
                        else if (reader["maintenance"].ToString() == "0")
                        {
                            btnAdd.BackColor = Color.BlueViolet;
                        }
                        btnAdd.Text = reader["name"].ToString();
                        btnAdd.Location = new Point(30, btnAdd.Bottom + 30);
                        MessageBox.Show(reader["name"].ToString());
                        panelEx1.Controls.Add(btnAdd);
                        
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

This code only shows one button or all the buttons placed one over one.

Thanks!

Dani AI

Generated

Nice first pass, . Two quick fixes to anchor your approach: (1) drop the unnecessary foreach (var element in reader); just iterate the reader with while (reader.Read()). (2) Always create a new Button inside that loop (as noted) and dispose DB objects with using so the reader/connection are closed even on errors. Also, prefer typed accessors like reader.GetBoolean(...) or Convert.ToInt32(...) over comparing .ToString() == "1".

For layout, let Windows Forms do the work. A FlowLayoutPanel will position buttons in rows and wrap automatically, so you do not have to track left/top or handle line breaks yourself. Set WrapContents = true, AutoScroll = true, then add buttons; call SuspendLayout/ResumeLayout around bulk adds to avoid flicker.

flowRooms.SuspendLayout();

using (var cmd = new MySqlCommand("SELECT roomid, name, maintenance, occupied FROM sah_rooms WHERE hotel_id = @id", con))
{
    cmd.Parameters.AddWithValue("@id", 1);
    using (var r = cmd.ExecuteReader())
    {
        while (r.Read())
        {
            var btn = new Button { Size = new Size(150, 80), Text = r.GetString("name") };
            btn.Tag = r.GetInt32("roomid"); // store the id safely
            btn.BackColor = r.GetBoolean("maintenance") ? Color.SkyBlue :
                            r.GetBoolean("occupied") ? Color.Yellow : SystemColors.Control;
            btn.Click += OnRoomClick;
            flowRooms.Controls.Add(btn);
        }
    }
}

flowRooms.ResumeLayout();

And your click handler stays simple and strongly typed:

private void OnRoomClick(object sender, EventArgs e)
{
    var btn = (Button)sender;
    int roomId = (int)btn.Tag;
    MessageBox.Show(roomId.ToString());
}

Extra tips:

  • If the UI pauses while loading many rooms, fetch data on a background thread and Invoke only the control creation.
  • Keep Name for designer lookups; use Tag for data. It avoids collisions and makes refactoring easier.

Recommended Answers

All 4 Replies

Need to initialize button each time like

Button btnAdd=new Button();

and set location correctly seem to be new point can't be changed.

Also Here you can get help. and also try this

int top = 50;
            int left = 100;

            for (int i = 0; i < 10; i++)
            {
                Button button = new Button();
                button.Left = left;
                button.Top = top;
                this.Controls.Add(button);
                top += button.Height + 2;
            }

Thanks I solved it here is the new code:

int top = 50;
                int left = 100;
                MySqlDataReader reader = comm.ExecuteReader();
                string roomid;
                while (reader.Read())
                {
                    foreach (var element in reader)
                    {

                        Button button = new Button();
                        button.Size = new System.Drawing.Size(150, 80);
                        button.Name = reader["roomid"].ToString();

                        button.Font = new Font("Trebuchet", 10);
                        if (reader["maintenance"].ToString() == "1")
                        {
                            button.BackColor = Color.SkyBlue;
                            button.Text = reader["name"].ToString() + "\n\n" + "Mantenimiento";
                        }
                        else if (reader["occupied"].ToString() == "1")
                        {
                            roomid = reader["roomid"].ToString();
                            button.BackColor = Color.Yellow;
                            button.Text = reader["name"].ToString() + "\n\n" + GetOccupatorName(roomid);
                            button.Click += new EventHandler(this.OnbClick);
                        }
                        else
                        {
                            button.Text = reader["name"].ToString();
                        }
                        
                        button.Left = left;
                        button.Top = top;
                        panelEx1.Controls.Add(button);
                        left += button.Width + 2;
                        if (left >= 500)
                        {
                            left = 100;
                            top += button.Height + 2;
                        }
                      
                    }
                }

Now the i need to assign to each button some function on click sending the name of the button as parameter, something like this:

button.Click += new EventHandler(this.OnbClick(buttonname));

//Here is the function

 private void OnbClick(object sender, EventArgs e, string buttonname)
        {
            MessageBox.Show(buttonname);
        }

Solved again:

void Onb2Click(object sender, EventArgs e)
        {
            Button btn = (Button)sender;
            string roomid = btn.Name.ToString();
            // btn.Enabled = false;
            btn.Enabled = false;
            MessageBox.Show(roomid);
        }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.