C#随机消失用户控制

时间:2018-02-07 05:25:08

标签: c# winforms

我构建了一个名为WebBrowser的Winforms EditableWebBrowser类的非常简单的扩展,除非在设计器代码中使用它的形式随机删除实例化,否则它的工作原理非常好。启动应用程序时,我似乎也偶尔会出现一些悬挂行为。没有什么特别的(自定义部分主要是字符串操作),除了两件事:

  1. 它使用SHDocVw引用来访问IHTMLDocument2对象。
  2. 它使用MSHTML高级接口来执行保存例程而不提示用户(使用ExecWB调用)。
  3. 但是,构造函数中既不使用SHDocVw也不使用MSHTML接口,并且在冻结时不会调用它们。

    控件如下所示:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Text.RegularExpressions;
    using System.IO;
    using SHDocVw;
    using mshtml;
    
    namespace WindowsFormsApp1.UserControls
    {
        public partial class EditableWebBrowser : System.Windows.Forms.WebBrowser
        {
            public string TempFile = "";
            public string TempFileURL { get { return "file:///" + TempFile.Replace('\\', '/'); } }
    
            // Private base constructor - we always want the parameterized public constructor
            private EditableWebBrowser()
            {
                InitializeComponent();
            }
    
            public EditableWebBrowser(bool editableOnDocumentCompleted = true, string localFile = "tmpEditableWebBrowser.html") : this()
            {
                // Set temp file
                this.TempFile = Path.GetTempPath() + localFile;
    
                // Make the loaded document editable?
                if(editableOnDocumentCompleted)
                {
                    this.DocumentCompleted += WebBrowser1_DocumentCompleted;
                }
            }
    
            // Handler for making the loaded document editable
            private void WebBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
            {
                IHTMLDocument2 doc = (IHTMLDocument2)this.Document.DomDocument;
                doc.designMode = "On";
            }
    
            // Some Regex objects and some custom methods here
    
            private string _cleanupImportedHTML(string HTML)
            {
                ...
            }
    
            public void Import(string HTML = null)
            {
                ...
            }
    
            public void Clear()
            {
                ...
            }
    
            public void SaveWithoutPrompt()
            {
                // Execute the browser's "Save" command without prompting
                object inVal = "";
                object outVal = "";
                ((IWebBrowser2)this.ActiveXInstance).ExecWB(SHDocVw.OLECMDID.OLECMDID_SAVE, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, ref inVal, ref outVal);
            }
        }
    }
    

    在使用它的表单的设计者(frmMain.Designer.cs)中,它只是:

    this.ewbContentEditor = new UserControls.EditableWebBrowser();
    

    这是偶尔删除的线,没有任何明显的模式。但是,引用它的其余设计器代码仍然保留在原位,这显然会破坏引用它的其余设计器代码:

    // 
    // ewbContentEditor
    // 
    this.ewbContentEditor.Dock = System.Windows.Forms.DockStyle.Fill;
    this.ewbContentEditor.Location = new System.Drawing.Point(3, 3);
    this.ewbContentEditor.MinimumSize = new System.Drawing.Size(20, 20);
    this.ewbContentEditor.Name = "ewbContentEditor";
    this.ewbContentEditor.Size = new System.Drawing.Size(599, 375);
    this.ewbContentEditor.TabIndex = 3;
    

    我想知道问题是否与公共构造函数的默认参数订阅了DocumentCompleted事件有关,但这是我此时唯一的想法,而且我不知道如何积极确认理论(没有明确的模式,我不想只是尝试一些事情,并假设它不会很快破裂)。

    其他人有任何想法或看到问题吗?

    此外,MSHTML接口是使用本文中描述的方法实现的: https://www.codeproject.com/Articles/2491/Using-MSHTML-Advanced-Hosting-Interfaces

1 个答案:

答案 0 :(得分:1)

你没有公共默认构造函数(你把它设为私有),设计师对此很挑剔。因此,如果你有一个应该得到设计者支持的控件,那么你需要一个默认的构造函数。

同样有意义的是检查你是否在Design Mode并且可能不会做一些你在运行时通常会做的事情,因为他们在设计模式中没有真正意义。