0

フォーム上にコントロール (checkBoxes、listBox、trackBar...) を動的に作成し、エディターを使用して menuStrip を配置しました。すべてのコントロールを削除したいのですが、メニューはそのままにしておきたいです。この行を使用する場合:

this.Controls.Clear();

メニューとコントロールを削除しますが、私が理解しているように、メニュー項目はコントロールではなく、フォーム上に直接あります(「これ」と書いてドットを押すと表示されます)。コントロールを循環させようとし、タイプがコントロールの 1 つである場合にのみ削除しましたが、一部のコントロールが削除されている間に一部のコントロールが残りました。私はcontrols.Countを使用して循環しました。サイクル全体を別の while() に置き、次のように Controls.Count > 1 の場合は終了しようとしました。

while( this.Controls.Count > 1 )
{
    for (int i = 0; i < this.Controls.Count; i++ )
    {
        if ((this.Controls[i].GetType() != typeof(MenuStrip)) ) 
        {
            this.Controls.RemoveAt(i);
        }
    }
}

コントロールを削除してメニューをそのままにしますが、消えるアイテムは同時に消えませんが、しばらくすると、whileが複数回実行されるためだと思います。
私の質問:
1. 上限として controls.count を使用して全体を反復処理しているときに、一度にすべてのコントロールを削除できないのはなぜですか。
2. toolStripMenuItmes はコントロールではありませんが、コントロールとしての menuStrip のポイントは何ですか。

4

1 に答える 1

1

これは、反復しているコレクションを変更するという典型的な間違いです。これを行うと、ほとんどのコレクション クラスは例外を生成しますが、残念ながら ControlCollection は例外を生成しません。誤動作するだけです。削除したコントロールの次のコントロールをスキップします。別の厄介なバグがあります。 Controls.RemoveAt() メソッドは、削除したコントロールを破棄せず、永久にリークします。

逆方向に反復することで、反復バグを回避します。そして、次のように適切に処分します。

for (int i = this.Controls.Count-1; i >= 0; i--) {
    if (this.Controls[i].GetType() != typeof(MenuStrip)) {
        this.Controls[i].Dispose();
    }
}
于 2013-10-05T17:53:10.830 に答える