2016-07-23 133 views
0

我试图做一个winForms应用程序,其中,每个增加numericUpDown应该,最终使面板控件可见,并创建一个文本框控件,一个picturebox,一个numericUpDown控件和三个标签。而每次减少,都应该删除这组控件。我设法编写了创建控件的代码,但我不知道如何删除它们。我唯一的猜测是,为每个控件分配一个名称,然后使用colorPanel.Controls.RemoveByKey()。不知道如何处理nameTextBoxPositionYnewLabelPositionY,在他们目前的状态下,他们可能会把所有事情搞砸。或者我应该放弃,并使用switch(regionNumber),手动创建控件,并根据numericUpDown值使它们可见?这将是很繁琐的事,考虑到对的NumericUpDown最大值为10如何以编程方式删除窗体控件

private Label newLabel; 
    private TextBox nameTextBox; 
    private NumericUpDown heightNumericUpDown; 
    private PictureBox colorPictureBox; 
    private string[] newLabelText = {"Name", "Height", "Color"}; 

    private int newLabelPositionX = -3; 
    private int newLabelPositionY = 5; 

    private int nameTextBoxPositionX = 74; 
    private int nameTextBoxPositionY = 2; 
    private void numberOfRegions_ValueChanged(object sender, EventArgs e) 
    {    
     int regionNumber = Convert.ToInt32(numberOfRegions.Value); 
     int numberOfLabels = 3;    

     if (regionNumber > 0) 
     { 
      colorPanel.Visible = true;               
      for (int i = 0; i < regionNumber; i++) 
      { 
       nameTextBox = new TextBox();          
       nameTextBox.Size = new System.Drawing.Size(81, 20); 
       nameTextBox.Location = new System.Drawing.Point(nameTextBoxPositionX, nameTextBoxPositionY); 
       colorPanel.Controls.Add(nameTextBox); 
       nameTextBoxPositionY += 78;              
       for (int a = 0; a < numberOfLabels; a++) 
       { 
        newLabel = new Label(); 
        newLabel.Location = new System.Drawing.Point(newLabelPositionX, newLabelPositionY); 
        newLabel.Text = newLabelText[a]; 
        colorPanel.Controls.Add(newLabel); 
        newLabelPositionY += 26;       
       }          
      } 
      newLabelPositionY = 5; 
      nameTextBoxPositionY = 2;    
     } 
     else 
     { 
      colorPanel.Visible = false; 
     }    
    } 
+0

这里的所有答案都有一个非常非常严重的错误。必须**处理您从其父母的Controls集合**中移除的控件。如果不这样做会导致垃圾收集器无法修复的永久内存泄漏。用任务管理器轻松诊断btw,添加USER对象列。您会看到您的流程显示的数量不断增加。您的程序在达到10,000时崩溃。 –

+0

那么应该如何应对这种控制?我想,这并不容易,因为在'for'循环中调用'nameTextBox.Dispose()'。 – amdmcm

+0

只需编写一个存储对这4个控件的引用的小结构。使用'Stack <>'来存储它们。现在很简单。 –

回答

0

感谢您的答案,但我ve搞乱了Controls.RemoveByKey(),发现解决办法:

struct DynamicFormControls 
{ 
    public TextBox textBox; 
    public Label label; 
} 

DynamicFormControls dynamicControls = new DynamicFormControls(); 
Stack<Control> controlStack = new Stack<Control>(); 
private string[] newLabelText = {"Name", "Height", "Color"}; 
private int newLabelPositionX = -3; 
private int newLabelPositionY = 5; 
private int nameTextBoxPositionX = 74; 
private int nameTextBoxPositionY = 2; 
private int numberOfLabels = 3; 
private int currentValue = 0; 
private int previousValue = 0; 
private int difference = 0; 
private int nameSuffix1 = 1; 
private int nameSuffix2 = 1; 

private void numberOfRegions_ValueChanged(object sender, EventArgs e) 
{ 
    currentValue = Convert.ToInt32(numberOfRegions.Value); 
    if (currentValue == 0) 
    { 
     colorPanel.Visible = false; 
     colorPanel.Size = new System.Drawing.Size(161, 10); 
    } 
    if (!ValueIncreased()) 
    { 
     RemoveControls(); 
    } 
    else 
    { 
     colorPanel.Visible = true;    
     CreateControls(); 
    } 
} 

private bool ValueIncreased() 
{ 
    if (currentValue > previousValue) 
    { 
     difference = currentValue - previousValue; 
     previousValue = currentValue; 
     return true; 
    } 
    else 
    { 
     difference = previousValue - currentValue; 
     previousValue = currentValue; 
     return false; 
    } 
} 

private void CreateControls() 
{ 
    for (int i = 0; i < difference; i++) 
    { 
     dynamicControls.textBox = new TextBox(); 
     dynamicControls.textBox.Name = "textBox" + nameSuffix1; 
     dynamicControls.textBox.Size = new System.Drawing.Size(81, 20); 
     dynamicControls.textBox.Location = new System.Drawing.Point(nameTextBoxPositionX, nameTextBoxPositionY);     
     colorPanel.Controls.Add(dynamicControls.textBox); 
     controlStack.Push(dynamicControls.textBox); 
     nameTextBoxPositionY += 78; 
     nameSuffix1++;     
     for (int a = 0; a < numberOfLabels; a++) 
     { 
      dynamicControls.label = new Label(); 
      dynamicControls.label.Name = "label" + nameSuffix2; 
      dynamicControls.label.Location = new System.Drawing.Point(newLabelPositionX, newLabelPositionY); 
      dynamicControls.label.Text = newLabelText[a]; 
      colorPanel.Controls.Add(dynamicControls.label); 
      controlStack.Push(dynamicControls.label); 
      newLabelPositionY += 26; 
      nameSuffix2++; 
     } 
    } 
} 

private void RemoveControls() 
{ 
    for (int d = 0; d < difference; d++) 
    {     
     for (int b = 0; b < 6; b++) 
     { 
      controlStack.Pop().Dispose(); 
     } 
     nameSuffix1--;    
     if (nameTextBoxPositionY > 2) 
     { 
      nameTextBoxPositionY -= 78; 
     } 
     for (int t = 0; t < numberOfLabels; t++) 
     { 
      nameSuffix2--; 
      if (newLabelPositionY > 5) 
      { 
       newLabelPositionY -= 26; 
      } 
     } 
    } 
} 
0

你可以简单地通过你的控制回路,并删除名字不需要的项目(假设你他们的名字存储阵列,甚至标签假设你指定一个数字标签给每个创建的控制(如regionNumber)

foreach (Control item in colorPanel.Controls.OfType<Control>()) 
{ 
    foreach(var name in myItemNames) 
    { 
     if (item.Name == name) 
     { 
      colorPanel.Controls.Remove(item); 
      item.Dispose(); 
      //... 

或者你可以只清除控制,如果这是你真正想要达到什么样的

colorPanel.Controls.Clear(); 

myItemNames在这里将是您在生成控件时分配的数组。例如

//before loop 
myItemNames = new List<string>(); 

//...in loop 
newLabel = new Label(); 
newLabel.name = "label"+i; 
myItemNames.Add(newLabel.name); 
0

使用Control.Controls.Remove方法:

this.Controls.Remove(Control); 

可能改变你的代码使用数组,然后就可以通过索引中删除控制:

TextBox[] MyTextBoxes = new TextBox[50]; 

foreach (TextBox textBox in MyTextBoxes) 
    this.Controls.Add(textBox); 

foreach (TextBox textBox in MyTextBoxes) 
    this.Controls.Remove(textBox);