【问题标题】:Update a lot of buttons or checkboxes?更新很多按钮或复选框?
【发布时间】:2018-03-13 13:45:17
【问题描述】:

我需要大约 200 个按钮来充当不同颜色的指示器,并且我有一个包含真假的列表,我想知道是否有一种方法可以更新它们而无需编写 200 个按钮的名称。 像这样的:

while (servoNumber != numberOfServos)
{
    if (Convert.ToBoolean(ListServo1Inputs[0 + inputToLookFor]) == true) 
    { 
        indicatorS1Di1.BackColor = Color.LawnGreen; 
    }
    else 
    { 
        indicatorS1Di1.BackColor = Color.DarkGray; 
    }
}

indicatorS1Di1.BackColor 也计数到循环中的下一行 S2。比如:indicatorS[increment number here]Di1.BackColor

也许这是一个简单的解决方案:

foreach (Control control in tabPage1.Controls.OfType<Button>())
{
    MessageBox.Show(control.GetType().ToString());

    if (control.Name first letters == "indicatorDi")
    {
        control.BackColor = Color.LawnGreen;
    }
} 

非常感谢兰德随机! 经过一些小的修改,这就是现在的样子:

【问题讨论】:

  • 您是如何创建按钮的?
  • 只是从工具箱中添加它们
  • 您已经使用方案指示器S1Di1 (SxDix) 为按钮命名,因此您最多可以将它们命名为200 - 指示器S200Di200?或类似的东西?或者只是简单地说你的命名约定是什么?
  • 到目前为止,我只添加了大约 20 个按钮并将它们命名为如上,但在此阶段可以更改任何内容。它的 s1di1、s1di2、s1di3 最多为 12,然后从 s2di1 重新开始,但正如我所说,如果它简化了其他内容,则可以更改。
  • 看看我的编辑。

标签: c# dictionary button indicator


【解决方案1】:

在您的加载事件中构建一个控件列表。

_buttons = new List<Button>(); //this is a field and not a local variable in the load event
for (var i = 0; i < ListServo1Inputs.Count; i++)
{
    _buttons.Add((Button)this.Controls.Find($"indicatorS{i}Di1", true).First());
}

要更新您的颜色,请使用以下命令:

for (var i = 0; i < ListServo1Inputs.Count; i++)
{
    //you can now use the same index for _controls and ListServo1Inputs - since you constructed a list of controls based on ListServo1Inputs in the loaded event
    _buttons[i].BackColor = Convert.ToBoolean(ListServo1Inputs[i]) ? Color.LawnGreen : Color.DarkGray;
}

编辑:

根据您的评论。

我会动态创建按钮。 在您的表单中,您需要一个带有点击事件的按钮和一个面板。

public partial class Form1 : Form
{
    //stores the booleans in a list
    private readonly List<bool> _values = new List<bool>();

    //I use a random to generate the booleans _random.Next(2) will produce either 0 or 1 and _random.Next(2) == 1 will give true on 1 and false on 0
    private readonly Random _random = new Random();

    public Form1()
    {
        InitializeComponent();

        //fill the list
        FillValues();

        //iterate over the list
        for (var index = 0; index < _values.Count; index++)
        {
            //create a button for each entry
            var btn = new Button();
            btn.Name = "Values" + index; //dont need the name, but you can fill it as you see fit
            btn.Width = 70; //set the width as you desire
            btn.Height = 20; //set the height as you desire
            btn.Text = btn.Name; //set a text if you like to, I used the .Name

            //some math to position the buttons, I here use a grid of 12 since you mentioned your naming scheme changes at 12 S1Di1 -> S1Di12 and than S2Di1 -> S2Di12
            btn.Top = (index / 12) * (btn.Height + btn.Margin.Top); 
            btn.Left = (index % 12) * (btn.Width + btn.Margin.Left);

            panel1.Controls.Add(btn); //add the button to a panel thats inside your form, only the buttons that get created here should be inside that panel nothing more
        }

        //update the colors of the button
        UpdateColors();
    }

    private void FillValues()
    {
        //clear the values, before filling it
        _values.Clear();

        //you mentioned 200 buttons, so here is a for loop for 200 entries and fill the values with a bool
        for (int i = 0; i < 200; i++)
            _values.Add(_random.Next(2) == 1);

        //of course you dont need to clear the list and re-add the items everytime this method gets called, you can check if (_values.Count == 0) and only than add the items and in else set the new values with _values[i] = newValue - its just the lazy way :)
    }
    private void UpdateColors()
    {
        //iterate over the list and set the panels Controls[index] to the color - the index will match with the list since you have created the buttons based on the list previously
        for (int i = 0; i < _values.Count; i++)
            panel1.Controls[i].BackColor = _values[i] ? Color.LawnGreen : Color.DarkGray;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        //to have new bools in list fill the values
        FillValues();

        //update the colors
        UpdateColors(); 
    }
}

这样你最终会得到:

当你按下按钮 1 时:

【讨论】:

    【解决方案2】:

    如果您自己创建这些按钮,您可以将它们放在字典中,并以您的增量名称作为键。

    然后您可以使用以下方法更改值:

    ServoButtonDict[$"indicatorS{incrementalNumber}Di1"].BackColor = Color.LawnGreen;
    

    【讨论】:

      【解决方案3】:

      您正在寻找一个 foreach 循环,这样您就可以动态地迭代按钮。

      foreach (var indicator in ListServoInputs) {
          if (indicator.Checked) {
              indicator.BackColor = Color.LawnGreen;
          } else {
              indicator.BackColor = Color.DarkGray;
          }
      }
      

      或者您可以使用ternary operator 进一步简化它,这对于简单但冗长的 if/else 语句非常有用。

      foreach (var indicator in ListServoInputs) {
          indicator.BackColor = indicator.Checked ? Color.LawnGreen : Color.DarkGray;
      

      【讨论】:

      • 嗯,您的意思是我将按钮的名称放在 ListServoInputs 列表中吗?本例中的 ListServoInputs 包含 200 行 true 和 false
      • 哦,我建议在初始化时创建一个 List
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 2014-07-14
      • 2014-02-12
      相关资源
      最近更新 更多