2016-07-23 108 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);