2

我有一个标签页,其中包含文本框、下拉列表、复选框、组框中的所有内容和一些标签。现在我想在用户单击按钮时清除所有控件。我应该如何实施?我进行了很多搜索,认为会有一个标准的库方法。我发现的只是一些带有 for-each 循环的方法(在组框内不起作用。)请指导我如何处理这个问题。基本上我想要一个像 Tabpage.load(); 这样的方法 它将选项卡带到其初始状态。如果可能的话,我想保留特定的文本框。

4

4 回答 4

7

很多 Winforms 程序员都把这种代码弄错了。到目前为止,您得到的答案也不例外。Controls.Clear() 和 Controls.Remove() 方法非常危险。这些方法按预期从其父级中删除控件,但它们不释放控件。它们被重新托管在一个名为“ParkingWindow”的内部隐藏窗口上。为了保持本机窗口处于活动状态,准备好移动到另一个父窗口。

这是一个非常好的功能,但不幸的是,这是无法控制的窗口句柄泄漏的主要来源。因为到目前为止,实际意图是处置它们,而不是重新托管它们。要永久删除控件,您必须使用他们的 Dispose() 方法。这也会自动将它们从 Controls 集合中删除。

这是第二个陷阱,您不能使用 foreach 来迭代 Controls 集合。这仅处理偶数编号的控件,这是集合被 foreach 循环修改的副作用。您必须向后迭代它,如下所示:

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

另外,不要Justin 那样递归。释放控件也会自动释放该控件的任何子控件。也许您的组框有问题,不是很清楚。

只是为了好玩,这是另一个真正驱动要点的实现:

    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

首先,您必须确定每种控件的“清晰”含义。即,它可能意味着将文本设置为 strimg.Empty 用于 TextBox,将 Checked 设置为 false 用于 CheckBox 并且对标签不执行任何操作。对于 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 回答