2

テキスト ボックス、ドロップダウン、チェック ボックス、グループ ボックス内の上記すべて、およびいくつかのラベルを含むタブ ページがあります。ユーザーがボタンをクリックしたときに、すべてのコントロールをクリアしたいと思います。どのように実装すればよいですか?標準ライブラリメソッドがあると思って、たくさん検索しました。私が見つけたのは、for-eachループを使用したいくつかのメソッドでした(グループボックス内では機能しません)。この問題の進め方を教えてください。基本的に、Tabpage.load(); のようなメソッドが必要です。タブを初期状態に戻します。可能であれば、特定のテキスト ボックスを保持したいと考えています。

4

4 に答える 4

7

多くの Winforms プログラマーは、この種のコードを誤解しています。これまでに得た答えも例外ではありません。Controls.Clear() および Controls.Remove() メソッドは非常に危険です。メソッドは、意図したとおりに親からコントロールを削除しますが、コントロールを破棄しません。それらは、「ParkingWindow」という名前の内部非表示ウィンドウで再ホストされます。ネイティブ ウィンドウを存続させ、別の親ウィンドウに移動できるようにします。

これは非常に優れた機能ですが、残念ながら制御不能なウィンドウ ハンドル リークの主な原因となっています。断然、実際の意図はそれらを破棄することであり、再ホストすることではないからです。コントロールを完全に削除するには、その Dispose() メソッドを使用する必要があります。Controls コレクションからも自動的に削除されます。

これは 2 番目のトラップです。foreach を使用して Controls コレクションを反復処理することはできません。これは、コレクションが foreach ループによって変更されることの副作用である、偶数番号のコントロールのみを破棄します。代わりに、次のように逆方向に反復する必要があります。

    public static void UnloadTabpage(TabPage page) {
        for (int ix = page.Controls.Count - 1; ix >= 0; --ix) {
            page.Controls[ix].Dispose();
        }
    }

また、ジャスティンのように再帰しないでください。コントロールを破棄すると、そのコントロールの子コントロールも自動的に破棄されます。グループ ボックスに問題がある可能性がありますが、あまり明確ではありません。

キックのために、これは本当に要点を家に追いやる別の実装です:

    public static void UnloadTabpage(TabPage page) {
        while (page.Controls.Count > 0) page.Controls[0].Dispose();
    }

しかし、それでは、やりたいと言ったように、コントロールを選択的に削除することは簡単ではありません。

于 2012-09-13T11:41:03.530 に答える
0

メソッドを使用しControlCollection.Clear()ます。MSDN

myTabControl.Controls.Clear()

特定のコントロールを保持したい場合は、次のいずれかを実行できます。

  • 列挙と条件チェックを使用して、必要なコントロールのみを削除します。
  • すべてのコントロールをクリアしてから、保持したいものだけを再読み込みします。

保持するコントロールの数と削除するコントロールの数によって異なります。

于 2012-09-13T10:50:46.273 に答える
0

まず、各種類のコントロールの「クリア」を意味するものを決定する必要があります。つまり、TextBox ではテキストを strimg.Empty に設定し、CheckBox では Checked を false に設定し、Label では何もしないことを意味します。GroupBox の場合、クリアはそのコントロールを再帰的にクリアすることを意味します。何をするかを決定したら、デリゲート タイプを定義し、コントロールのタイプがキーであるこれらのデリゲートのディクショナリを作成できます。これで、適切なデリゲートを適用してコントロール コレクションをループできます。コードは説明よりも簡単です。

public delegate void ClearControl(Control aCtrl);

private static Dictionary<Type, ClearControl> _clearDelegates;

public static Dictionary<Type, ClearControl> ClearDelegates
{
    get 
    { 
        if (_clearDelegates== null)
            InitializeClearDelegates();
        return _clearDelegates; 
    }
}

private static void InitializeClearDelegates()
{
    _clearDelegates= new Dictionary<Type, ClearControl>();
    _clearDelegates[typeof(TextBox)] = new ClearControl(delegate(Control aCtrl) 
    {
        ((TextBox)aCtrl).Text = string.Empty;
    });
    _clearDelegates[typeof(CheckBox)] = new ClearControl(delegate(Control aCtrl)
    {
        ((CheckBox)aCtrl).Checked = false;
    });
    _clearDelegates[typeof(GroupBox)] = new ClearControl(delegate(Control aCtrl)
    {
        foreach (Control innerCtrl in ((GroupBox)aCtrl).Controls)
            Clear(innerCtrl);
    });
    _clearDelegates[typeof(TabPage)] = new ClearControl(delegate(Control aCtrl)
    {
        foreach (Control innerCtrl in ((TabPage)aCtrl).Controls)
            Clear(innerCtrl);
    });
    // ... other controls
}

public static object Clear(Control aCtrl)
{
    ClearControl aDel;
    if (ClearDelegates.TryGetValue(aCtrl.GetType(), out aDel))
        aDel(aCtrl);
}
于 2012-09-13T14:39:59.557 に答える
-1

これは私にとってはうまくいきます.GroupBoxが含まれています.

    void ClearControls(Control parent)
    {
        while (parent.Controls != null && parent.Controls.Count > 0)
        {
            ClearControls(parent.Controls[0]);
            parent.Controls.Remove(parent.Controls[0]);
        }
    }
于 2012-09-13T10:52:58.753 に答える