动态添加和重新定位文本框

时间:2017-02-17 07:01:35

标签: c# .net winforms

我有简单的窗体来获取用户详细信息。如果用户希望通过点击" +"添加备用手机号码按钮,文本框应显示在其下方,其他文本框应根据新添加的文本框重新定位。 我能够在运行时动态添加文本框,但无法相对于动态添加的文本框重新定位其他表单组件。下面是我的代码和表单快照。提前谢谢。

private void button1_Click(object sender, EventArgs e)
{
    TextBox txtRun = new TextBox();
    txtRun.Name = "txtDynamic" + c++;
    txtRun.Location = new System.Drawing.Point(90, 74 + (20 * c));
    txtRun.Size = new System.Drawing.Size(200, 25);
    txtRun.Location.X = 90;
    txtRun.Location.Y = 74;
    this.Controls.Add(txtRun);
}

User details windows form

3 个答案:

答案 0 :(得分:1)

尝试将所有控件(姓名,电子邮件,手机,城市等)添加到FlowLayoutPanel并将其添加到您的窗口:

var panel = new FlowLayoutPanel() { FlowDirection = FlowDirection.TopDown }
panel.Controls.Add(namePanel);
panel.Controls.Add(emailPanel);
// etc

当用户点击+按钮时,将新控件插入所需位置:

panel.Controls.Insert(3, newControlPanel); // add new control at index #3

如果您还没有这样做,则可能需要将每个Label - TextBox对包装在自己的Panel中,以便流布局按预期工作。这可以通过编程方式完成:

private void InitializeForm()
{
    var layoutPanel = new FlowLayoutPanel();
    // todo: initialize flow layout panel here...

    layoutPanel.Controls.Add(CreatePanel("Name"));
    layoutPanel.Controls.Add(CreatePanel("Email"));
    // etc

    this.Controls.Add(layoutPanel);
}

private Panel CreatePanel(string labelText)
{
    var label = new Label(labelText);
    // todo: initialize label here...

    var textBox = new TextBox();
    // todo: initialize textbox here...

    var panel = new Panel();
    panel.Controls.Add(label);
    panel.Controls.Add(textBox);
    // todo: initialize panel here...

    return panel;
}

当每个面板以完全相同的方式添加时,此方法还可以帮助您的表单看起来更加一致。例如,边距和填充都可以在一个位置更改。

答案 1 :(得分:0)

每个Form对象都有Controls列出的位置&存储了所有对象。您正在访问它并在此代码中添加TextBox

this.Controls.Add(txtRun);

您可以决定如何处理案例,因为有更多解决方案。您可以浏览所有控件,查找低于MobileTextBox的控件,然后向下移动几个像素。

或者您可以将MobileTextBox下面的控件分组到某个GroupBox(或其他分组控件)中,然后移动GroupBox

和/或是@gt - FlowLayoutPanel提到的解决方案,它将以与WPF framework类似的方式处理布局。

一些代码示例:

private void button1_Click(object sender, EventArgs e)
{
    TextBox txtRun = new TextBox();
    txtRun.Name = "txtDynamic" + c++;
    txtRun.Location = new System.Drawing.Point(90, 74 + (20 * c));
    this.Controls.Add(txtRun);

    //removed some code for brevity


    //1st solution
    foreach(Control item in this.Controls)
    {
        //there can be some other condition
        //based on e.g. name of TB
        //or if the type is GroupBox with some name

        if(item.Location.Y >= txtRun.Location.Y)
           item.Location.Y = item.Location.Y + 25; 

    }

}

答案 2 :(得分:0)

试试这个,

int c = 0; // for uinque txtDynamic text creation 
private void button1_Click(object sender, EventArgs e)
{
      TextBox txtDynamic = this.Controls.Find("txtDynamic" + c, true)[0] as TextBox; // find lastly added txtDynamic 

      TextBox txtRun = new TextBox();
      txtRun.Name = "txtDynamic" + ++c;
      txtRun.Size = new System.Drawing.Size(100, 20);
      txtRun.Location = new Point(txtDynamic.Location.X, txtDynamic.Location.Y + 35); // X axis will be same y will increase with count 35


      foreach (Control item in this.Controls)
      {
           if (item.Location.Y >= txtRun.Location.Y){ // if there is an item that has greater Y location
               item.Location = new Point(item.Location.X, txtRun.Location.Y + 35); // It should increase its value as 35 too.
           }
           this.Controls.Add(txtRun);

      }
}

修改1:

好的,我用拖放创建了控件,我不知道你是否以编程方式创建它们。 + 按钮将在Mobil TextBox之后添加新的文本框。所以我拖动和下垂的Mobile TextBox将是最重要的一点。所以我把它的名字命名为“ txtDynamic0 ”,

enter image description here

将断点放在button1_click上,我的c变量的值与0的值不同,我想是起点。

<强>结果; enter image description here

希望有所帮助,