【问题标题】:Disabling a dynamic button禁用动态按钮
【发布时间】:2013-02-05 17:49:12
【问题描述】:

您好,我有一个小型的 winforms 程序,它很快就会发展成更多的东西。该程序有 2 个面板 panel1panel2 这些面板动态填充了一些表单控件。第一个面板填充了组合框,第二个面板填充了按钮网格。我想要实现的是能够根据用户从combobox 中选择的内容禁用右键。网格的每一列代表一周中的一天,combobox 将用于禁用所需的日期,如果您愿意,可以从列表中选择它。

静态执行此操作很简单,但是我的程序很快就会扩展,以便它可以处理大型数据库,这就是我动态执行此操作的原因。基本上这就是我现在想简单地禁用右键的地方。

下面是我目前的界面:

如果有帮助,这是我的代码:

 public Form1()
        {
            InitializeComponent();
        }
        Button[] btn = new Button[2];
        ComboBox[] cmb = new ComboBox[1];

        private void Form1_Load(object sender, EventArgs e)
        {
            placeRows();
        }

        public void createColumns(int s)
        {
            for (int i = 0; i < btn.Length; ++i)
            {
                btn[i] = new Button();
                btn[i].SetBounds(40 * i, s, 35, 35);
                btn[i].Text = Convert.ToString(i);

                panel1.Controls.Add(btn[i]);

            }

            for (int i = 0; i < cmb.Length; ++i)
            {
                cmb[i] = new ComboBox();
                cmb[i].SelectedIndexChanged += new EventHandler(cmb_SelectedIndexChanged);
                cmb[i].Text = "Disable";
                cmb[i].Items.Add("Monday");
                cmb[i].Items.Add("Tuesday");
                cmb[i].SetBounds(40 * i, s, 70, 70);
                panel2.Controls.Add(cmb[i]);
            }

        }

        void cmb_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox senderCmb = (ComboBox)sender;

            if (senderCmb.SelectedIndex == 1)
            {
                //MessageBox.Show("Tuesday");
                btn[1].Enabled = false;
            }
        }

        public void placeRows()
        {
            for (int i = 0; i < 80; i = i + 40)
            {
                createColumns(i);               
            }
        }
    }

【问题讨论】:

    标签: c# arrays winforms


    【解决方案1】:

    备选方案 1

    每个控件都有一个Tag 属性。

    您可以设置按钮的Tag 属性来表示它们所在的列。

    当在组合框中进行选择时,只需搜索所有按钮,然后根据每个按钮的Tag 属性是否与组合框中的选定文本匹配来启用或禁用按钮。

    备选方案 2

    创建一个

    Dictionary<string, List<Button>> buttonMap;
    

    其中键是代表列的值(“星期二”),值是带有该标签的按钮列表。最初创建按钮时,还要填充该字典。

    如果您使用备选方案 2,则必须记住先前选择的复选框值,以便重新启用不再禁用的按钮。

    如果您有很多按钮,您可能会发现备选方案 2 明显更快。

    更新

    这是备选方案 1 的完整工作示例。

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        const int ROWS = 2;
        const int COLS = 2;
    
        Button[,] btn = new Button[ROWS,COLS];
        ComboBox[] cmb = new ComboBox[ROWS];
    
        private void Form1_Load(object sender, EventArgs e)
        {
            placeRows();
        }
    
        private readonly string[] cbTexts = new string[] { "Monday", "Tuesday" };
    
        public void createColumns(int rowIndex)
        {
            int s = rowIndex * 40;
    
            // Your original code kept overwriting btn[i] for each column.  You need a 2-D array
            // indexed by the row and column
            for (int colIndex = 0; colIndex < COLS; colIndex++)
            {
                btn[rowIndex, colIndex] = new Button();
                btn[rowIndex, colIndex].SetBounds(40 * colIndex, s, 35, 35);
                btn[rowIndex, colIndex].Text = Convert.ToString(colIndex);
                btn[rowIndex, colIndex].Tag = cbTexts[colIndex];
    
                panel1.Controls.Add(btn[rowIndex, colIndex]);
    
            }
    
            cmb[rowIndex] = new ComboBox();
            cmb[rowIndex].SelectedIndexChanged += new EventHandler(cmb_SelectedIndexChanged);
            cmb[rowIndex].Text = "Disable";
            foreach (string cbText in cbTexts)
            {
                cmb[rowIndex].Items.Add(cbText);
            }
            cmb[rowIndex].SetBounds(40, s, 70, 70);
            cmb[rowIndex].Tag = rowIndex; // Store the row index so we know which buttons to affect
            panel2.Controls.Add(cmb[rowIndex]);
    
        }
    
        void cmb_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox senderCmb = (ComboBox)sender;
    
            int row = (int)senderCmb.Tag;
            for (int col = 0; col < COLS; col++)
            {
                Button b = btn[row, col];
                // These three lines can be combined to one.  I broke it out
                // just to highlight what is happening.
                string text = ((string)b.Tag);
                bool match =  text == senderCmb.SelectedItem.ToString();
                b.Enabled = match;
            }
        }
    
        public void placeRows()
        {
            for (int rowIndex = 0; rowIndex < 2; rowIndex++)
            {
                createColumns(rowIndex);
            }
        }
    }
    

    【讨论】:

    • 我会试试这个,但在我尝试之前我需要改变我创建按钮的方式吗?
    • @Tacit:不是真的。如果您使用备选方案 1,只需添加 btn[i].Tag = "Monday" (等等......您需要知道每个列在哪一列)。首先选择备选方案 1。如果速度太慢,请尝试备选方案 2。
    • 我有点挣扎,你能不能给个更详细的例子
    • 感谢您的帮助我现在正在尝试您建议的解决方案我实际上正在考虑使用二维数组,因为它更有意义
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    • 2021-11-08
    相关资源
    最近更新 更多