简体   繁体   English

使用Dispose()从窗体中删除控件

[英]Using Dispose() to remove Control from Form

Is it correct to use Dispose() to remove a Control from a Form? 使用Dispose()从窗体中删除控件是否正确?

Eg I have a button 'button1' on my formular. 例如,我的配方器上有一个按钮“ button1”。 When calling Dispose() it immediately disappears from the form and also from the 'Controls'-Collection of the form. 调用Dispose()时,它会立即从表单以及表单的“控件” -Collection中消失。 But is this always the case? 但是,总是这样吗? Or are there other cases (maybe other controls) where the GC waits some time? 还是在其他情况下(也许是其他控件)GC等待一段时间?

This "bonus" of Control.Dispose is not documented. 没有记录Control.Dispose这种“奖励”。

As a general tip, you should not build your program around expectations that undocumented behavior stays the same for the future, or even across all current control implementations. 作为一般性提示,您不应围绕期望未记录的行为在将来甚至在所有当前控件实现中保持不变的期望来构建程序。

However, as you can see from the Reference Source of Control.Dispose(bool) : 但是,正如您从Control.Dispose(bool)参考源中所看到的:

if (parent != null) {
    parent.Controls.Remove(this);
}

This does indeed happen in the current implementation. 这确实在当前实现中发生。

But again, this is not documented behavior. 但是,这又没有记录在案的行为。 Make of it what you will. 随心所欲。

From MSDN : MSDN

This method is called by the public Dispose method and the Finalize method. 公共Dispose方法和Finalize方法调用此方法。 Dispose invokes the protected Dispose(Boolean) method with the disposing parameter set to true. Dispose将Dispose参数设置为true来调用受保护的Dispose(Boolean)方法。 Finalize invokes Dispose with disposing set to false. Finalize将Dispose设置为false来调用Dispose。

So I think no problem. 所以我认为没问题。

Should you call Dispose()? 您应该调用Dispose()吗?

Whenever you see any class that implements System.IDisposable you should assume that the designer of the class thinks that the class might hold some scarce resources. 每当您看到实现System.IDisposable的任何类时,都应假定该类的设计者认为该类可能包含一些稀缺资源。

You are not obliged to call Dispose() of objects of these classes. 您没有义务调用这些类的对象的Dispose()。 If you don't, the finalizer will. 如果您不这样做,则终结器将这样做。 However if you don't call Dispose(), the scarce resource is held longer than needed, possibly leading to insufficient resources. 但是,如果不调用Dispose(),则稀缺资源的保存时间将超过所需时间,这可能导致资源不足。

So indeed, before assigning null to your Control you should call Control.Dispose(). 因此,确实,在为控件分配null之前,应调用Control.Dispose()。

Should you remove the control from the control collection before disposing the control? 处置控件之前,应该从控件集合中删除控件吗?

Apparently the current implementation makes sure that disposed controls are removed from the control collection in control.Parent.Controls. 显然,当前实现可确保从control.Parent.Controls中的控件集合中删除已处置的控件。

However, depending on your implementation, are you sure that the ControlCollection where you added your control is not a subclass of System.Windows.Forms.Control.ControlCollection, with a slightly different behaviour? 但是,根据您的实现,您确定添加控件的ControlCollection不是System.Windows.Forms.Control.ControlCollection的子类,其行为有所不同吗? After all: ControlCollection is not sealed. 毕竟:ControlCollection没有密封。 Even if you made your own form with your own ControlCollection, people might derive from your form with its own ControlCollection. 即使您使用自己的ControlCollection制作了自己的表单,人们也可能会使用自己的ControlCollection来继承自您的表单。

Hence, to make sure that yo follow the rules of handling the ControlCollection I think you should remove the control from the collection before disposing it. 因此,为确保您遵循处理ControlCollection的规则,我认为您应在处置之前从集合中删除控件。

// Create myControl and add to myForm
var myControl = new MyControl(...);
myControl.SetProperties
myForm.Controls.Add(myControl);

// proper removal:
// if someone else could already have removed the control:
// add a check if it is still there.
myForm.Control.Remove(myControl);
myControl.Dispose();    // no problem if already disposed
myControl = null;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM