使用 button_click 事件在表单中加载多个 Groupbox

Loading multiple Groupboxes in the form using the button_click event

提问人:Paras 提问时间:2/2/2023 最后编辑:IVSoftwareParas 更新时间:2/2/2023 访问量:130

问:

我希望使用 button_click 事件在 Windows 窗体应用程序中加载多个组框。

每次单击按钮时,表单中都应显示一个组框。

Screenshot of my expected output预期输出。


我无法使组框的位置动态化,因为第二个组框应该与第一个组框保持一定距离。我想过手动计算坐标并使用点数组作为位置,但我觉得应该有更好的方法来解决这个问题。

我定义了“int count=0”变量来计算按钮被点击的次数。基于此,我命名了新的组框。但我认为 count++ 行中使用的逻辑存在一些问题。它不会追求 1。因此,我只得到一个分组框“groupBox1”。当我再次单击该按钮时,没有任何反应。

感谢您的帮助。

谢谢

int count=0;
private GroupBox GetGroupBox(int a)
{
     GroupBox groupBox = new GroupBox();
     groupBox.Text = "groupBox"+(a.ToString());
     groupBox.Width= 200;
     groupBox.Height= 200;
     groupBox.Location = new Point(50,400);
     return groupBox;            
 }
 private void button1_Click(object sender, EventArgs e)
 {              
     count++;                       
     this.Controls.Add(GetGroupBox(count));           
 }
C# WinForms 按钮 组框

评论

0赞 Dmitry Bychenko 2/2/2023
位置不能是恒定的,groupBox.Location = new Point(50,400);groupBox.Location = new Point(50 + count * (groupBox.Width + 10), 400);

答:

1赞 Dmitry Bychenko 2/2/2023 #1

由于您想从左到右创建框,因此您应该进行调整:例如,第一个框应该有,第二个,3d等。LeftLeft = 50Left = 270Left = 490

法典:

const int deltaX = 20;
...
//TODO: check do you really want Top = 400, not, say, 20?
groupBox.Location = new Point(50 + (a - 1) * (groupBox.Width + deltaX), 400);
...

简化的实施可以是

int count = 0;

// Let's rename the method: we actually create GroupBox, not get existing
private GroupBox CreateGroupBox(int index) => new GroupBox() {
  Text     = $"groupBox{index}",
  Size     = new Size(200, 200),
  Location = new Point(50 + (index - 1) * (20 + 200), 400),
  Parent   = this, // Instead of Controls.Add()
};

private void button1_Click(object sender, EventArgs e) {
  CreateGroupBox(++count);  
}

评论

0赞 Paras 2/2/2023
非常感谢@Dmitry的帮助。它现在可以工作了。你介意启发我为什么当我多次点击按钮时计数没有增加吗?如果我的问题太简单,请原谅我,因为我是编码新手。
0赞 Dmitry Bychenko 2/2/2023
@Paras:在问题的代码中,您确实增加了 ,但您没有使用它 - 请注意,这没有使用 或countGetGroupBoxacount
1赞 IV. 2/2/2023 #2

您的问题陈述了这些目标:

  • 根据事件动态添加一个(如按钮点击)。GroupBox
  • 分配新位置。GroupBox
  • 用“一段距离”填充位置。

你说你“觉得应该有更好的方法来解决这个问题”,确实如此!


尝试尝试使用一个本质上处理所有这三个问题的方法。FlowLayoutPanel

screenshot


下面是我用来添加和删除 实例的代码。这是我添加到项目中的 UserControl,但它适用于任何类型的控件。CustomGroupBox

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        numericUpDownGroupboxes.ValueChanged += onGroupBoxCountChanged;
        foreach (var radio in Controls.OfType<RadioButton>())
        {
            radio.CheckedChanged += onFlowLayoutDirectionChanged;
        }
    }

当数字上下更改时,将预期的组框数与当前计数进行比较。或者,您可以继续使用按钮单击并直接转到 。flowLayoutPanel.Controls.Add(...)

    private void onGroupBoxCountChanged(object sender, EventArgs e)
    {
        // Need an int for comparison.
        int 
            countIs = flowLayoutPanel.Controls.OfType<CustomGroupBox>().Count(),
            countShouldBe = (int)numericUpDownGroupboxes.Value;
        switch(countIs.CompareTo(countShouldBe))
        {
            case -1:
                flowLayoutPanel.Controls.Add(
                    new CustomGroupBox
                    {
                        Name = $"groupBox{countShouldBe}",
                        Text = $"GroupBox {countShouldBe}",
                        Size = new Size(300, 150),
                        Margin = new Padding(10),
                        BackColor = Color.White,
                    });
                break;
            case 1:
                Control last = flowLayoutPanel.Controls.OfType<CustomGroupBox>().Last();
                flowLayoutPanel.Controls.Remove(last);
                break;
        }
    }

也可以指定流动的方向

    private void onFlowLayoutDirectionChanged(object sender, EventArgs e)
    {
        if(radioButtonHorizontal.Checked)
        {
            flowLayoutPanel.FlowDirection = FlowDirection.LeftToRight;
        }
        else
        {
            flowLayoutPanel.FlowDirection = FlowDirection.TopDown;
        }
    }
}