WebBrowser.Document.Body is always null

ⅰ亾dé卋堺 提交于 2019-12-04 03:17:51
Nathan Andrew Mullenax

You have to wait for the Web Browser's DocumentCompleted event to fire for the DomDocument.Body to not be null. I just tested this to verify. I suppose the question still remains: how are you able to edit through the underlying COM interface when the document has not completely loaded?

I checked to see if the IHTMLDocument2 pointers were the same in DocumentCompleted and the constructor. They are, which might indicate that the underlying COM object reuses a single HTML document object. It seems like any changes you make in the constructor at least have a pretty good chance of getting overwritten or throwing an exception.

For example, if I do this in the constructor, I get an error:

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

p1.title = "Hello world!";

If I do the same in a DocumentCompleted handler, it works fine.

Hope this helps. Thanks.

Use DocumentCompleted event first, it occurs when the WebBrowser control finishes loading a document:

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;
}

or simple way:

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;
            };
}

You need to let the WebBrowser control to work alone a bit to give it some time to set the Document.Body property.

I do that by calling Application.DoEvents();.

For instance in your code:

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;
}
if (HtmlEditor.Document.Body == null)
{
   HtmlEditor.Document.OpenNew(false).Write(@"<html><body><div id=""editable""></div></body></html>");
}
HtmlEditor.Document.Body.SetAttribute("contentEditable", "true");
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!