【问题标题】:How to delete (remove) space between textboxes after remove some controls?删除某些控件后如何删除(删除)文本框之间的空格?
【发布时间】:2019-01-31 20:40:44
【问题描述】:

我是 C# 的新手,我在这里询问是因为我没有在谷歌中找到解决方案搜索和其他关于 SO 的问题,我将解释我的示例应用程序的作用:

当我运行它时,它默认显示一个带有文本框的表单,这个文本框总是会显示,在输入一些文本并按下回车后,它将生成一个新文本框和一个新按钮(所有控件甚至默认文本框都是在面板内),并且新文本框具有与默认文本框相同的功能,当我单击其文本框旁边生成的按钮时,它会删除按钮本身和文本框,但之后如果我删除一些随机文本框它会留下一个空间在这些控件之间,如何重新组织这些内容以不让它们之间有空间?

正如您在图片中看到的那样,您能告诉我如何解决此问题或给我建议以实现此目标吗?谢谢,这是我用来生成按钮和文本框的方法

private void GenerarTextBox()
{
    panelContenedor.VerticalScroll.Value = panelContenedor.VerticalScroll.Minimum;

    TextBox tb = new TextBox();
    tb.Text = "Prueba " + id;
    tb.Name = "txtBox" + id;
    tb.KeyDown += new KeyEventHandler(TextBox_Keydown);

    Button bt = new Button();
    bt.Cursor = Cursors.Hand;
    bt.Text = "X";
    bt.Name = "btnPrueba" + id;
    bt.Click += new EventHandler(ClickBotones);

    Point p = new Point(20, 30 * id);
    Point pb = new Point(130, 30 * id);

    tb.Location = p;
    bt.Location = pb;

    panelContenedor.Controls.Add(tb);
    panelContenedor.Controls.Add(bt);

    tb.Focus();
    id++;
}

这是删除文本框和按钮

private void ClickBotones(object sender, EventArgs e)
{
    Button bt = sender as Button;

    string nombreBoton = bt.Name;
    string idBoton = nombreBoton.Substring(9);
    string nombreTextBox = "txtBox" + idBoton;

    foreach (Control item in panelContenedor.Controls.OfType<Control>())
    {
        if (item.Name == nombreTextBox)
        {
            panelContenedor.Controls.Remove(item);
            panelContenedor.Controls.Remove(bt);
        }
    }
}

【问题讨论】:

  • 您是否尝试更改位置属性?这通常可以改变位置
  • 为什么投反对票?
  • 我不确定你为什么投了反对票(这实际上是一个写得很好的问题),但考虑到你的样本表明对设置位置属性的认识,这似乎是一个奇怪的问题添加控件时的控件,以及添加控件时的育儿概念。似乎您自然会得出结论,您需要更新其他控件的位置来解决此问题。话虽如此,@Oliver 关于定义 UserControls 和 FlowLayoutPanel 的回答是一个更好的解决方案,因为它消除了您处理此类概念的必要性。
  • 您实际上可以通过封装您在此处添加的控件的 UserControls 以及面板内这些用户控件的 Docking 属性来实现相同的隐式行为

标签: c# button textbox panel


【解决方案1】:

您可以将动态控件放在FlowLayoutPanel 上。直接或在PanelUserControl 中组合在一起。

FlowLayoutPanelFlowDirection 属性设置为TopDown。然后FlowLayoutPanel 将自动排列您的控件。您还可以将WrapContents 属性设置为False 并将AutoScroll 设置为true 以使滚动条出现。

或者您可以使用FlowDirection = LeftToRight,将文本框和按钮直接放在FlowLayoutPanel 上并让子控件换行(WrapContents = True)。在子控件中,将出现一个新属性 FlowBreak。可以将其设置为True,以使最后一个控件连续出现,并让下一个控件独立于FlowLayoutPanel 的宽度进行换行。

您还可以使用子控件的Margin 属性来控制它们在FlowLayoutPanel 中的布局,因为Location 属性变得无用。

FlowLayoutPanel(以及Panel)位于“容器”部分的工具箱中。

【讨论】:

  • 我会试试这个,我会告诉你的。
  • 我试过了,但它不会生成滚动条并从上到下生成文本框和按钮,当达到 flowlayout 的限制时,它开始在右侧生成新闻
  • 我在回答中添加了更多解释。玩转FlowLayoutPanelFlowDirectionWrapContentsAutoScroll 属性以及子控件的FlowBreakMargin 属性。要测试它们的行为,在设计器中的FlowLayoutPanel 上放置一些控件会更容易。手动调整面板大小以查看会发生什么。我测试了我的答案中描述的 2 个替代方案(FlowDirection = TopDownLeftToRight)并且两者都有效。
【解决方案2】:

当您删除控件时,您需要重新计算位置。因此,当您按顺序添加它们时,您可以使用:

bool repos = false;
Point p;
foreach (Control item in panelContenedor.Controls.OfType<Control>())
    {
        if (repos)
        {
             Point tmp = item.Location;              
             item.Location = p;
             p = tmp;
        }


        if (item.Name == nombreTextBox)
        {
            panelContenedor.Controls.Remove(item);
            panelContenedor.Controls.Remove(bt);
            repos = true;
            p = item.Location;
        }

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    • 2020-02-28
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    相关资源
    最近更新 更多