代码之家  ›  专栏  ›  技术社区  ›  AlWooz

C#-具有动态数据输入的动态按钮

  •  0
  • AlWooz  · 技术社区  · 7 年前

    我这里有点问题。

    我试图用可变数据创建动态clickevents。

    for(int i = 0; i < data.Devices.Length; i++)
    {
        Button _button = new Button();
        _button.Size = new Size(100, 15);
        _button.Text = data.Devices[i].Alias;
        _button.Name = "textbox" + i.ToString();
        _button.Location = new Point(x,y);
        x += 110;
    
        if(x > 1850)
        {
            y += 50;
            x = 10;
        }
    
        if (data.Devices[i].OnlineState == "Online")
        {
            _button.BackColor = Color.Green;
        }
        else
        {
            _button.BackColor = Color.Red;
        }
    
         _button.Click += (Sender, args) =>
         {
             MessageBox.Show(data.Devices[i].Alias);
         };
    
         Controls.Add(_button);
     }
    

    这里的想法是,我将创建按钮,直到完成列表的长度(这些对象的列表和位置不同)。

    我要找的是制作一组按钮,当你点击按钮时,你会打开另一个屏幕,上面有一些附加到该对象的统计信息。

    由于数据会有很大差异,因此没有办法对每个场景进行硬编码,但我希望做的事情与您在Android中可以做的相同,请参见下文。

    for (int i = 1; i <= 20; i++) {
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    
        Button btn = new Button(this);
        btn.setId(i);
        final int id_ = btn.getId();
        btn.setText("button " + id_);
        btn.setBackgroundColor(Color.rgb(70, 80, 90));
        linear.addView(btn, params);
        btn1 = ((Button) findViewById(id_));
    
        btn1.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                Toast.makeText(view.getContext(), "Button clicked index = " + id_, Toast.LENGTH_SHORT).show();
        }
    });
    

    我有什么办法可以做到这一点吗?

    致以诚挚的问候。

    2 回复  |  直到 7 年前
        1
  •  2
  •   PeteGO    7 年前

    我认为你遇到的问题是关于 closures .

    在您的示例中,您正在添加事件处理程序,其中包含一个引用变量的委托 i 这会改变每个循环迭代。因此,当事件处理程序实际执行时(当单击按钮时) 一、 超出范围。

    你可以这样做:

    private void Form1_Shown(object sender, EventArgs e)
    {
        var items = new[] { "Item One", "Item Two", "Item Three", "Item Four", "Item Five" };
    
        for (int i = 0; i < items.Length; i++)
        {
            var btn = new Button
            {
                Text = $"Button {i + 1}",
                Tag = items[i]
            };
    
            btn.Click += (object obj, EventArgs args) 
                =>
                {
                    MessageBox.Show($"Hello.  {((Button)obj).Tag}");
                };
    
            flowLayoutPanel1.Controls.Add(btn);
        }
    }
    

    在您的情况下,按钮的标签可以设置为 data.Devices[i]

        2
  •  0
  •   AlWooz    7 年前

    我首先用创建按钮并将其放置在屏幕上。

    for (int i = 0; i < data.Devices.Length; i++){
    Button _button = new Button();
    _button.Size = new System.Drawing.Size(100, 55);
    _button.Text = data.Devices[i].Alias;
    _button.Name = "dynamicButton";
    _button.FlatStyle = FlatStyle.Flat;
    _button.Tag =   data.Devices[i].Alias + "|" + 
                    data.Devices[i].DeviceId + "|" + 
                    data.Devices[i].LastSeen + "|" + 
                    data.Devices[i].OnlineState + "|" + 
                    data.Devices[i].Description + "|" + 
                    data.Devices[i].RemotecontrolId; 
    
    _button.Location = new System.Drawing.Point(x, y);
    x += 110;
    if (x > 1850)
    {
        y += 60;
        x = 30;
    }
    _button.Click += new EventHandler(bt_click);
    Controls.Add(_button);
    }
    

    然后使用onclick事件。

    protected void bt_click(object sender, EventArgs e)
        {
            Button btn = sender as Button;
            String[] information = btn.Tag.ToString().Split('|');
            String present = "Namn: " + information[0]
                            + "\nDeviceID: " + information[1]
                            + "\nSenast uppe: " + information[2]
                            + "\nStatus: " + information[3]
                            + "\nEmail: " + information[4]
                            + "\nTW-ID: " + information[5];
            MessageBox.Show(present);
            //DO THE THINGS WITH THE INFORMATION                
        }
    

    for (int i = 0; i < 10; i++)
            {
                foreach (Control item in Controls.OfType<Control>())
                {
                    if (item.Name == "dynamicButton")
                    {
                        Controls.Remove(item);                        
                    }
                }
            }
    

    出于某种原因,我不得不循环几次,因为它不会将它们全部删除,而是以某种模式删除它们。 (每次只取一次)

    我绕了10圈以获得良好的效果。

    它正是我想要它做的,新设备会自动添加,而删除的设备也会很快消失。