【问题标题】:How Can I Generate Dynamic Buttons in Winforms based on the data table values from Database in C#?如何根据 C# 数据库中的数据表值在 Winforms 中生成动态按钮?
【发布时间】:2020-06-11 05:54:54
【问题描述】:

实际上,我对 C# 还是很陌生。我在数据库中有两个表,分别命名为“Categories”和“MenuItems”。我想要的是当表单加载时,我应该从数据库中获取所有类别行并将它们显示为动态生成的按钮上的文本(按钮的数量取决于类别行的数量),我已经使用以下代码完成了它:

   private void Form1_Load(object sender, EventArgs e)
    {
        SqlConnection con = new SqlConnection();
        con.ConnectionString = "Data Source=Shezi;Initial Catalog=RMS;Integrated Security=True";
        SqlCommand cmd = new SqlCommand();
        con.Open();
        string commandText = "select Categories From Categories";
        cmd = new SqlCommand(commandText, con);
        SqlDataReader sdr = cmd.ExecuteReader();
        DataTable dt = new DataTable();
        dt.Load(sdr);
        con.Close();
        int btnName = 0;
        if (dt.Rows.Count>0)
        {
            btnName++;

            int PosY = 5;
            int rowCount = -1;
            int numOfRows = dt.Rows.Count;
            for(int i=0; i<numOfRows; i++)
            {
                rowCount++;
                foreach (DataRow row in dt.Rows)
                {
                    variables.btnText = dt.Rows[rowCount].Field<string>(0); 
                }
                Button button = new Button();
                button.Enabled = true;
                button.Text = variables.btnText;
                button.BackColor = Color.Green;
                button.ForeColor = Color.White;
                button.Width = 150;
                button.Height = 50;
                button.Name = "button" + btnName;
                button.Location = new Point(-2, PosY);
                button.Font = new Font("Georgia", 12);
                button.Click += Button_Click;
                panel.Controls.Add(button);
                PosY += 55;
            }
        }



    }

我上面的代码确实根据数据库中的类别行生成动态按钮,这是我的主要问题,我想要的是当用户单击任何动态生成的按钮时,应该在菜单项中搜索该按钮的文本(显然按钮的文本将是类别文本),应用程序应在 MenuItems 行中搜索该文本并过滤掉针对该类别保存的所有 MenuItems(例如,如果动态生成的按钮具有文本“Burger”,则程序应获取所有菜单汉堡类别中的项目并显示在更多新生成的动态按钮上),类似地,如果单击具有类别奶酪的按钮,它应该获取并创建新的动态按钮并填充奶酪菜单项。 这是我迄今为止尝试根据按钮点击获得新的动态按钮:

 private void btn1_Click(object sender, EventArgs e)
    {

        dt = manager.GetMenuItems(menuItems);
        var count = dt.Rows.Count;
        //int btnName = 0;

        int PosX = 160;
        int rowCount = -1;
        for (int i = 0; i < count; i++)
        {
            //btnName++;
            rowCount++;
            foreach (DataRow row in dt.Rows)
            {
                menuItems.MenuText = dt.Rows[rowCount].Field<string>(0);
                //categories.btnText = row.Field<string>("Categories", DataRowVersion.Original);//do not undo
                DataView dv = dt.DefaultView;
                dv.RowFilter = "MenuItem = MenuItem";
                DataTable dt1 = dv.ToTable();
                menuItems.MenuText = dt1.ToString();
            }
            //string btnText = count.ToString();
            Button btn1 = new Button();
            btn1.Enabled = true;
            btn1.Text = menuItems.MenuText;

            btn1.BackColor = Color.Navy;
            btn1.ForeColor = Color.White;
            btn1.Width = 150;
            btn1.Height = 50;
            btn1.Name = "btn1";


            btn1.Location = new Point(PosX, 10);
            btn1.Font = new Font("Georgia", 12);
            btn1.Click += new EventHandler(btn1_Click);
            pnlCategories.Controls.Add(btn1);
            PosX += 150;

            //var newvalue =  ds.Tables[0].Rows[1].ItemArray[0].ToString();    

        }


    }

我已经搜索了很多方法但找不到类似的东西,我也在 stackoverflow 上尝试了不同的线程但没有运气,需要帮助!

【问题讨论】:

  • MenuItems Table 中有哪些列?
  • 使用如下:string[] columnNames = dt.Columns.Cast().Select(x => x.ColumnName).ToArray();

标签: c# winforms


【解决方案1】:

试试下面的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication62
{
    public partial class Form1 : Form
    {
        static DataTable dt = new DataTable();
        const int NUMBER_OF_BUTTON_COLUMNS = 6;
        const int BUTTON_HEIGHT = 50;
        const int BUTTON_WIDTH = 50;
        const int BUTTON_MARGIN = 50;


        public Form1()
        {
            InitializeComponent();

            for (int i = 0; i < 20; i++)
            {
                dt.Columns.Add("Col_" + i.ToString(), typeof(string));
            }
            AddButtons();
        }

        public void AddButtons()
        {
            String[] columnNames = dt.Columns.Cast<DataColumn>().Select(x => x.ColumnName).ToArray();
            for(int i = 0; i < columnNames.Length; i++)
            {

                Button button = new Button();
                button.Text = columnNames[i];
                int column = i % NUMBER_OF_BUTTON_COLUMNS;
                int row = i / NUMBER_OF_BUTTON_COLUMNS;
                button.Left = column * (BUTTON_MARGIN + BUTTON_WIDTH);
                button.Top = row * (BUTTON_MARGIN + BUTTON_HEIGHT);
                button.Width = BUTTON_WIDTH;
                button.Height = BUTTON_HEIGHT;
                this.Controls.Add(button);
                button.Click +=new EventHandler(Button_Click);
            }

        }
        public void Button_Click(object sender, EventArgs e)
        {
            Button button = sender as Button;
            string buttonName = button.Text;
        }


    }
}

【讨论】:

    【解决方案2】:

    我希望这是你需要的

    void GenerateButton(FlowLayoutPanel pnl)
            {
                Button CategoryButton = new Button
                {
                    Enabled = true,
                    Text = ItemName,
                    BackColor = Color.Green,
                    ForeColor = Color.White,
                    Width = 150,
                    Height = 50,
                    Name = ItemName,
                    Font = new Font("Georgia", 12)
                };
    
                void SearchItemsInThisCategory(object sender , EventArgs e)
                {
                    foreach(Button button in pnl.Controls.OfType<Button>())  //Remove others categories buttons
                    {
                        if (button.Name != CategoryButton.Name)
                        {
                            pnl.Controls.Remove(button);
                        }
                    }
                    using (SqlConnection con = new SqlConnection("Data Source=Shezi;Initial Catalog=RMS;Integrated Security=True"))
                    {
                        SqlDataAdapter dataAdapter = new SqlDataAdapter($"select {CategoryButton.Text} From MenuItems", con);
                        DataTable dt = new DataTable();
                        dataAdapter.Fill(dt);
    
    
                        foreach (DataRow row in dt.Rows)
                        {
                            ItemName = row[CategoryButton.Text].ToString(); 
                            GenerateButton(pnl);
                        }
    
                    }
    
                }
                CategoryButton.Click += SearchItemsInThisCategory;
                pnl.Controls.Add(CategoryButton);
            }
    
            public void GetAllCategories(FlowLayoutPanel pnl)
            {
                using (SqlConnection con = new SqlConnection("Data Source=Shezi;Initial Catalog=RMS;Integrated Security=True"))
                {
                    SqlDataAdapter dataAdapter = new SqlDataAdapter("select Categories From Categories", con);
                    DataTable dt = new DataTable();
                    dataAdapter.Fill(dt);
    
    
                    foreach (DataRow row in dt.Rows)
                    {
                        ItemName = row["Categories"].ToString(); //Assume Categories columns contains all categories
                        GenerateButton(pnl);
                    }
    
                }
    
            }
    

    测试

    public string ItemName { get; set; }
            private void Form1_Load(object sender, EventArgs e)
            {
                GetAllCategories(flowLayoutPanel1);
            }
    

    说明

    我建议你使用 FlowLayoutPanel 而不是 Panel

    我已经声明了名为 ItemName 的属性,它将接收 Form1_Load 中的每个 CategoryName 并且 CategoryButton Name 和 Text 将等于 ItemName

    我在生成的按钮中添加了 onClick 事件 - 首先删除除自身以外的其他按钮 - 然后它将使用它的文本在 MenutItem 表中仅选择“ColumnName”,然后检索所有行数据并将每个行单元格值再次分配给 GeneratedButton

    【讨论】:

    • 是的,听起来不错
    【解决方案3】:

    **嗨,别介意专家我解决了这个问题,方法是获取动态按钮文本,然后在数据库中搜索它以获取针对它存储的菜单项,这里是代码:**

    using BusinessManager;
    using DataAccess;
    using Domain;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace RestuarnetManagementSystem.Softangles
    {
        public partial class POS : Form
        {
            Manager manager = new Manager();
            DataClass dataClass = new DataClass();
            Categories categories = new Categories();
            DataTable dt = new DataTable();
            DataSet ds = new DataSet();
            ButtonData bd = new ButtonData();
            MenuItems menuItems = new MenuItems();
            int btnName = 0;
            public POS()
            {
                InitializeComponent();
            }
    
            private void tabPage1_Click(object sender, EventArgs e)
            {
    
            }
    
            public void panel7_Paint(object sender, PaintEventArgs e)
            {
                //ds.Tables[0].Rows[i].ItemArray[0].ToString()
    
                //dt = manager.DeployButtonCategoryText(categories);
                dt = manager.DeployButtonCategoryText(categories);
                var count = dt.Rows.Count;
                //int btnName = 0;
    
                int PosY = 5;
                int rowCount = -1;
                for (int i = 0; i < count; i++)
                {
                    //btnName++;
                    rowCount++;
                    btnName++;
                    foreach (DataRow row in dt.Rows)
                    {
                        categories.btnText = dt.Rows[rowCount].Field<string>(0);
                        //categories.btnText = row.Field<string>("Categories", DataRowVersion.Original);
                    }
                    //string btnText = count.ToString();
                    Button btn1 = new Button();
                    btn1.Enabled = true;
                    btn1.Text = categories.btnText;
                    categories.btnText = btn1.Text;
                    btn1.BackColor = Color.Navy;
                    btn1.ForeColor = Color.White;
                    btn1.Width = 150;
                    btn1.Height = 50;
                    btn1.Name = "btn1"+btnName;
    
    
                    btn1.Location = new Point(-2, PosY);
                    btn1.Font = new Font("Georgia", 12);
                    btn1.Click += new EventHandler(btn1_Click);
                    pnlCategories.Controls.Add(btn1);
                    PosY += 55;
    
                    //var newvalue =  ds.Tables[0].Rows[1].ItemArray[0].ToString();
                }
    
    
    
    
            }
    
            private void POS_Load(object sender, EventArgs e)
            {
    
    
    
    
    
            }
    
            private void btn1_Click(object sender, EventArgs e)
            {
                pnlMenuItems.Controls.Clear();
                Button btn = sender as Button;
                 menuItems.FindMenuItems = btn.Text;
                  dt =  manager.GetMenuItems(menuItems);
                 int rowCount = dt.Rows.Count;
                int counter = -1;
                if(dt.Rows.Count>0)
                {
    
                    int PosX = 100;
                    for (int i = 0; i < rowCount; i++)
                    {
                        btnName++;
                        counter++;
                        foreach (DataRow row in dt.Rows)
                        {
                            menuItems.MenuText = dt.Rows[counter].Field<string>(0);
                        }
    
                        Button button = new Button();
                        button.Enabled = true;
                        button.Text = menuItems.MenuText;
                        button.BackColor = Color.Navy;
                        button.ForeColor = Color.White;
                        button.Font = new Font("Georgia", 12);
                        button.Location = new Point(PosX, 10);
                        button.Width = 150;
                        button.Height = 50;
                        button.Name = "button" + btnName;
                        button.Click += new EventHandler(button_Click);
                        pnlMenuItems.Controls.Add(button);
                        PosX += 150;
                    }
                }
                else
                {
                    MessageBox.Show("Failed!");
                }
                //dt = manager.GetMenuItems(menuItems);
                //int count = dt.Rows.Count;
                ////int btnName = 0;
    
                //int PosX = 160;
                //int rowCount = -1;
                //for (int i = 0; i < count; i++)
                //{
                //    //btnName++;
                //    rowCount++;
                //    foreach (DataRow row in dt.Rows)
                //    {
                //       menuItems.MenuText = dt.Rows[rowCount].Field<string>(0);
    
                //    }
                //    //string btnText = count.ToString();
                //    Button btn2 = new Button();
                //    btn2.Enabled = true;
                //    btn2.Text = menuItems.MenuText;
    
                //    btn2.BackColor = Color.Navy;
                //    btn2.ForeColor = Color.White;
                //    btn2.Width = 150;
                //    btn2.Height = 50;
                //    btn2.Name = "btn2";
    
    
                //    btn2.Location = new Point(PosX, 10);
                //    btn2.Font = new Font("Georgia", 12);
                //    btn2.Click += new EventHandler(btn2_Click);
                //    pnlCategories.Controls.Add(btn2);
                //    PosX += 150;
    
                //    //var newvalue =  ds.Tables[0].Rows[1].ItemArray[0].ToString();    
    
            }
    
            private void button_Click(object sender, EventArgs e)
            {
                MessageBox.Show("Test");
            }
    
    
        }
    
    
    }
    

    【讨论】:

      猜你喜欢
      • 2021-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-30
      • 1970-01-01
      • 1970-01-01
      • 2022-09-27
      相关资源
      最近更新 更多