【问题标题】:WebBrowser.Document.Body is always nullWebBrowser.Document.Body 始终为空
【发布时间】:2011-12-29 18:36:59
【问题描述】:

我有一个WebBrowser 文档设置为编辑模式。我正在尝试使用WebBrowser.Document.Body.InnerText 来操作body 元素的内部文本,但是WebBrowser.Document.Body 仍然为空。

这是我创建文档内容的代码:

private WebBrowser HtmlEditor = new WebBrowser();
public HtmlEditControl()
{
    InitializeComponent();
    HtmlEditor.DocumentText = "<html><body></body></html>";
    myDoc = (IHTMLDocument2)HtmlEditor.Document.DomDocument;
    myDoc.designMode = "On";
    HtmlEditor.Refresh(WebBrowserRefreshOption.Completely);
    myContentsChanged = false;
}

我可以编辑代码并且一切正常,但我不明白为什么HtmlEditor.Document.Body 仍然为空。我知道每当我需要将文本加载到表单中时,我总是可以重置文档正文,但我更愿意了解为什么会这样,如果没有别的,那就是知识。

非常感谢您对此的任何帮助。

【问题讨论】:

标签: c# .net winforms webbrowser-control


【解决方案1】:

您必须等待 Web 浏览器的 DocumentCompleted 事件触发,DomDocument.Body 才不会为空。我只是对此进行了测试以验证。我想问题仍然存在:当文档没有完全加载时,你如何能够通过底层的 COM 接口进行编辑?

我检查了 DocumentCompleted 和构造函数中的 IHTMLDocument2 指针是否相同。它们是,这可能表明底层 COM 对象重用了单个 HTML 文档对象。似乎您在构造函数中所做的任何更改至少很有可能被覆盖或引发异常。

例如,如果我在构造函数中这样做,我会得到一个错误:

IHTMLDocument2 p1 = (IHTMLDocument2) HTMLEditor.Document.DomDocument;

p1.title = "Hello world!";

如果我在 DocumentCompleted 处理程序中做同样的事情,它工作正常。

希望这会有所帮助。谢谢。

【讨论】:

    【解决方案2】:

    首先使用DocumentCompleted事件,它在WebBrowser控件完成加载文档时发生:

    public HtmlEditControl()
    {
        InitializeComponent();
        HtmlEditor.DocumentText = "<html><body></body></html>";
        HtmlEditor.DocumentCompleted += HtmlEditorDocumentCompleted;
    }
    
    void HtmlEditorDocumentCompleted(object sender, 
                                     WebBrowserDocumentCompletedEventArgs e)
    {
        myDoc = (IHTMLDocument2)((WebBrowser)sender).Document.DomDocument;
        myDoc.designMode = "On";
        HtmlEditor.Refresh(WebBrowserRefreshOption.Completely);
        myContentsChanged = false;
    }
    

    或者简单的方法:

    public HtmlEditControl()
    {
        InitializeComponent();
        HtmlEditor.DocumentText = "<html><body></body></html>";
        HtmlEditor.DocumentCompleted += (sender, e) =>
                {
                    myDoc = (IHTMLDocument2) HtmlEditor.Document.DomDocument;
                    myDoc.designMode = "On";
                    HtmlEditor.Refresh(WebBrowserRefreshOption.Completely);
                    myContentsChanged = false;
                };
    }
    

    【讨论】:

      【解决方案3】:

      您需要让WebBrowser 控件单独工作一点,以便给它一些时间来设置Document.Body 属性。

      我通过调用Application.DoEvents();来做到这一点。

      例如在您的代码中:

      private WebBrowser HtmlEditor = new WebBrowser();
      public HtmlEditControl()
      {
          InitializeComponent();
          HtmlEditor.DocumentText = "<html><body></body></html>";
      
          // Let's leave the WebBrowser control working alone.
          while (HtmlEditor.Document.Body == null)
          {
              Application.DoEvents();
          }
      
          myDoc = (IHTMLDocument2)HtmlEditor.Document.DomDocument;
          myDoc.designMode = "On";
          HtmlEditor.Refresh(WebBrowserRefreshOption.Completely);
          myContentsChanged = false;
      }
      

      【讨论】:

        【解决方案4】:
        if (HtmlEditor.Document.Body == null)
        {
           HtmlEditor.Document.OpenNew(false).Write(@"<html><body><div id=""editable""></div></body></html>");
        }
        HtmlEditor.Document.Body.SetAttribute("contentEditable", "true");
        

        【讨论】:

          猜你喜欢
          • 2017-07-31
          • 2019-07-18
          • 2019-08-18
          • 2019-07-02
          • 2019-05-04
          • 1970-01-01
          • 2011-05-04
          • 2015-10-29
          • 2015-07-11
          相关资源
          最近更新 更多