2016-07-23 7 views
0

私はwinFormsアプリケーションを作成しようとしています。ここで、numericUpDownの各値を増やすと、パネルコントロールが表示され、テキストボックスコントロール、ピクチャボックス、numericUpDownコントロール3つのラベル。それぞれの減少は、このコントロールのグループを削除する必要があります。私は、コントロールを作成するコードを記述することができましたが、私はそれらを削除する方法がわかりません。私の唯一の推測は、すべてのコントロールに名前を割り当てて、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

おかげで、私は」:

this.Controls.Remove(Control); 

たぶん、あなたはインデックスでコントロールを削除することができ、配列を使用するようにコードを変更します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方法:答えを

TextBox[] MyTextBoxes = new TextBox[50]; 

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

foreach (TextBox textBox in MyTextBoxes) 
    this.Controls.Remove(textBox); 
関連する問題