WebBrowser.Document.Body всегда нулевой - PullRequest
8 голосов
/ 15 ноября 2011

У меня WebBrowser документ установлен в режим редактирования. Я пытаюсь манипулировать внутренним текстом элемента body с помощью WebBrowser.Document.Body.InnerText, однако 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 остается нулевым. Я знаю, что всегда могу просто сбросить тело документа всякий раз, когда мне нужно загрузить текст в форму, но я бы предпочел понять, почему это ведет себя так, как есть, если не что иное, как знание.

Любая помощь в этом очень приветствуется.

Ответы [ 4 ]

6 голосов
/ 20 июля 2012

Вам нужно подождать, пока событие веб-браузера DocumentCompleted не сработает, чтобы DomDocument.Body не было нулевым. Я только что проверил это, чтобы проверить. Я предполагаю, что вопрос все еще остается: как вы можете редактировать через базовый интерфейс COM, когда документ еще не полностью загружен?

Я проверил, совпадают ли указатели IHTMLDocument2 в DocumentCompleted и в конструкторе. Это так, что может указывать на то, что базовый COM-объект повторно использует один объект документа HTML. Кажется, что любые изменения, которые вы вносите в конструктор, имеют, по крайней мере, довольно хороший шанс переписать или вызвать исключение.

Например, если я делаю это в конструкторе, я получаю ошибку:

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

p1.title = "Hello world!";

Если я делаю то же самое в обработчике DocumentCompleted, он работает нормально.

Надеюсь, это поможет. Спасибо.

2 голосов
/ 20 июля 2012

Сначала используйте 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;
            };
}
0 голосов
/ 23 августа 2013
if (HtmlEditor.Document.Body == null)
{
   HtmlEditor.Document.OpenNew(false).Write(@"<html><body><div id=""editable""></div></body></html>");
}
HtmlEditor.Document.Body.SetAttribute("contentEditable", "true");
0 голосов
/ 08 августа 2012

Вы должны позволить элементу управления 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;
}
...