首页 > 解决方案 > 为什么我必须从 Controls 中删除一个控件并重新添加它才能再次显示?

问题描述

给定以下代码 winform 代码:

   public partial class WebBrowserForm : Form
    {
        public WebBrowserForm()
        {
            InitializeComponent();
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            Previewer.Show();
            this.webBrowser1.Refresh();
            Previewer.Navigate("http://google.com");
        }

        private WebBrowser Previewer
        {
            get
            {
                if(webBrowser1 == null || webBrowser1.IsDisposed)
                {
                    //Controls.Remove(webBrowser1); 

                    webBrowser1 = new WebBrowser();

                    //Controls.Add(webBrowser1);

                    this.webBrowser1.Location = new System.Drawing.Point(12, 12);
                    this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20);
                    this.webBrowser1.Name = "webBrowser1";
                    this.webBrowser1.Size = new System.Drawing.Size(776, 250);
                    this.webBrowser1.TabIndex = 0;
                    this.webBrowser1.Show();                    
                }

                return webBrowser1;
            }
        }

        private void btnDispose_Click(object sender, EventArgs e)
        {
            webBrowser1.Dispose();
        }
    }

如果我单击“加载”,然后单击“处理”,然后再次“加载”,WebBrowser 控件不会重新出现在表单上。

如果我删除它,新建一个并重新添加到控件中,WebBrowser 控件将按预期工作。(取消注释下面的两行以使示例正常工作)。

为什么我必须删除并重新添加到控件才能使示例正常工作?

标签: c#winforms

解决方案


我在这里(在源代码中)找到了 Component(虚拟 Dispose 方法实现)的答案:https ://referencesource.microsoft.com/#System/compmod/system/componentmodel/Component.cs,ec402748f4bd1220

protected virtual void Dispose(bool disposing) {
    if (disposing) {
        lock(this) {
            if (site != null && site.Container != null) {
                site.Container.Remove(this);
            }
            if (events != null) {
                EventHandler handler = (EventHandler)events[EventDisposed];
                if (handler != null) handler(this, EventArgs.Empty);
            }
        }
    }
}

当您调用 dispose(除非被覆盖)时,它会将自己从其父级(容器)中删除。


推荐阅读