我有一个标签页,其中包含文本框、下拉列表、复选框、组框中的所有内容和一些标签。现在我想在用户单击按钮时清除所有控件。我应该如何实施?我进行了很多搜索,认为会有一个标准的库方法。我发现的只是一些带有 for-each 循环的方法(在组框内不起作用。)请指导我如何处理这个问题。基本上我想要一个像 Tabpage.load(); 这样的方法 它将选项卡带到其初始状态。如果可能的话,我想保留特定的文本框。
4 回答
很多 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();
}
但这并不容易让您有选择地删除控件,就像您提到的那样。
使用ControlCollection.Clear()
方法。MSDN
myTabControl.Controls.Clear()
如果要保留某些控件,您可以
- 使用枚举和条件检查仅删除您需要的控件。
- 清除所有控件,然后仅读取要保留的控件。
这取决于您要保留多少控件与要删除多少控件。
首先,您必须确定每种控件的“清晰”含义。即,它可能意味着将文本设置为 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);
}
这对我有用,包括 GroupBox,
void ClearControls(Control parent)
{
while (parent.Controls != null && parent.Controls.Count > 0)
{
ClearControls(parent.Controls[0]);
parent.Controls.Remove(parent.Controls[0]);
}
}