Элемент управления WebBrowser и GetElement по идентификатору

Я использую Visual C # Winforms для управления объектом WebBrowser.

В частности, я хочу использовать WebBrowser.Document.GetObjectByID ("myid"). Style, чтобы установить стиль объекта, который является частью документа, загруженного в объект WebBrowser.

Я хочу, чтобы кнопка на WinForm переключала стиль заголовка с «display: none» на «display: block; text-align: middle». Вот что я делаю:

private void frmView_Load(object sender, EventArgs e)
{
string question = "How many cows?";
string answer = "5 cows";
webBrowser1.Navigate("about:blank");
webBrowser1.Document.OpenNew(false);
webBrowser1.Document.Write("<html><body><div id='question'><h1>");
webBrowser1.Document.Write(question);
webBrowser1.Document.Write("</h1></div><div id='answer'><h2>");
webBrowser1.Document.Write(answer);
webBrowser1.Document.Write("</h2></div></body></html>");
webBrowser1.Refresh();
webBrowser1.Document.GetElementById("answer").Style = "display:none;";
//if I do a breakpoint here, I get the Style = "DISPLAY:NONE"
btnAnswer.Visible = true;
btnNext.Visible = true;
}

private void btnAnswer_Click(object sender, EventArgs e)
{
//if this is the first time ran, doing a breakpoint here will
//show Style to be NULL
webBrowser1.Document.GetElementById("answer").Style = "display:block;text-align:center";
//now the Style is properly set, and will remain that way, even after this function returns}

Обратите внимание, что я могу управлять свойством Style с помощью метода btnAnswer_Click, но не с помощью метода frmView_Load. Я знаю, что могу просто поместить информацию о стиле в тег div при его создании (это действительно работает), но почему приведенный выше код не работает?

Обновление:
Я нашел кое-что, что, возможно, идет в правильном направлении. Если я вызываю webBrowser1.Update() в любой момент после webBrowser1.Navigate("about:blank"), все в frmView_Load работает. К сожалению, любые попытки изменить документ после выхода из frmView_Load потерпят неудачу. Они не только не сработают, но и после того, как frmView_Load вернет webBrowser1.Document каким-то образом будет установлено значение NULL. Может ли кто-нибудь пролить свет на то, как этот элемент управления должен работать?


person Gorchestopher H    schedule 02.03.2012    source источник
comment
Какой WebBrowser элемент управления вы используете? Windows Forms? WPF?   -  person John Saunders    schedule 02.03.2012
comment
System.Windows.Forms.WebBrowser   -  person Gorchestopher H    schedule 02.03.2012
comment
Ваш вопрос немного запутан, я попробовал код и нажатие кнопки в форме (это не ‹кнопка ввода›, не так ли?) Меняет ответ на белый или черный. Еще одна вещь, которая отличается для меня, - это после того, как я выхожу из этой функции, свойство .Style имеет значение null, стиль был установлен для меня. Можете ли вы отредактировать свой вопрос, чтобы иметь исходный HTML-код для события FormLoad и иметь событие button_click для изменения цвета, таким образом, его будет легко воспроизвести для всех.   -  person Jeremy Thompson    schedule 02.03.2012
comment
Я обновил свой вопрос, чтобы показать больше. Неожиданное поведение заключается в том, что я могу установить стиль в моем form_Load, но этот стиль каким-то образом отбрасывается после выхода из form_Load. Если я нажму btnAnswer, он покажет стиль как NULL, но после (даже после того, как он вернется или будет повторно вызван), он покажет правильно установленный стиль.   -  person Gorchestopher H    schedule 02.03.2012
comment
@JeremyThompson Если я использую кнопку для изменения стиля, она работает. Но, как вы можете видеть в новом опубликованном мной коде, по какой-то причине метод FormLoad не устанавливает стиль навсегда. Я думаю, что есть какая-то команда finalize, которую я не отправляю после инициализации страницы, что автоматически происходит после функции инициализации. Имеет ли это смысл?   -  person Gorchestopher H    schedule 02.03.2012


Ответы (3)


Изучив документацию MS по элементу управления WebBrowser, я понял, что все, что делает браузер, является асинхронным. Сказав это, это означает, что я должен заблокировать свои потоки управления после установки свойств, чтобы гарантировать, что эти свойства были установлены.

По сути, моя «запись» в документ не выполняется только потому, что функция «записи» возвращается. Я должен заблокировать поток управления до тех пор, пока документ не отразит эти изменения, если я хочу сослаться на содержимое этой записи. MS рекомендует цикл сна. Вот как выглядит моя функция записи и блокировки:

private void ChangeDocument(string documentText, double timeout)
{
    DateTime startTime = DateTime.Now;
    double elapsed = 0;

    if (webBrowser1.Document == null)
    {
        webBrowser1.Navigate("about:blank");
    }

    webBrowser1.Document.OpenNew(false);

    while ((webBrowser1.DocumentText != "") && (elapsed < timeout))
    {
        Thread.Sleep(50);
        elapsed = DateTime.Now.Subtract(startTime).TotalMilliseconds;
    }

    webBrowser1.Document.Write(documentText);

    startTime = DateTime.Now;
    elapsed = 0;

    while ((webBrowser1.DocumentText != documentText) && (elapsed < timeout))
    {
        System.Threading.Thread.Sleep(50);
        elapsed = DateTime.Now.Subtract(startTime).TotalMilliseconds;
    }
}

Всем спасибо за ответы.

person Gorchestopher H    schedule 04.03.2012

Почему бы вам не поместить скрытый текст в <div> со стилем display:none? Когда вам нужно его показать, вам просто нужно будет обновить стиль display. Вы также можете применить этот стиль к элементу h2, который содержит ваш ответ в вашем примере кода.

person xxbbcc    schedule 02.03.2012
comment
Что ж, я попробовал ваше предложение, но эффект такой же, как и то, что я делаю сейчас. Первоначально я применял стиль к элементу H2, но теперь я использую DIV. Я думаю, что мне может не хватать какого-то триггера события. Если я сделаю вторую кнопку только для установки стиля, она сработает. Но если я использую ту же функцию для создания HTML и изменения стиля, этого не произойдет. - person Gorchestopher H; 02.03.2012

Я не очень хорошо знаком с этим, но я бы подумал, что вам нужно позвонить

webBrowser1.Refresh();

в самом конце frmView_Load

person dice    schedule 02.03.2012
comment
Пробовал и это тоже, разницы нет. Кроме того, метод btnAnswer_Click не вызывает обновления и может обновлять стиль без проблем. - person Gorchestopher H; 02.03.2012