【问题标题】:C# randomly disappearing User ControlC# 随机消失的用户控件
【发布时间】:2018-07-17 07:33:48
【问题描述】:

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

  1. 它使用 SHDocVw 引用来访问 IHTMLDocument2 对象。
  2. 它使用 MSHTML 高级接口来执行保存例程而不提示用户(使用 ExecWB 调用)。

但是,在构造函数中既没有使用 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

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    您没有公共的默认构造函数(您将其设为私有)并且设计者对此很挑剔。因此,如果您有一个应该得到设计器支持的控件,您将需要一个默认构造函数。

    此外,检查您是否在 Design Mode 中也很有意义,并且可能不做一些您在运行时通常会做的事情,因为它们在设计模式下没有真正意义。

    【讨论】:

    • 并确保在设计模式下不抛出异常。
    • 令我困惑的是它可以工作一段时间 - 设计师似乎(暂时)可以使用只有默认参数的公共构造函数。您能否详细说明“设计对此很挑剔”是什么意思?
    • 您的代码示例显示private EditableWebBrowser()。这会产生问题。
    • 当您编辑设计器并打开设计模式后,一切看起来都已找到。但是,一旦您通过设计器编辑表单,您的 Designer.cs 就会被完全重写,然后就会出现问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多