WebBrowser Control and GetElement by ID

一笑奈何 提交于 2019-12-21 21:31:49

问题


I am using Visual C# Winforms to control a WebBrowser object.

Specifically I want to use WebBrowser.Document.GetObjectByID("myid").Style to set the style of an object that is part of the document loaded into the WebBrowser object.

I want to have button on the WinForm toggle the Style of a heading from "display:none" to "display:block;text-align:middle". This is what I am doing:

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}

Note that I am able to control the Style property with the btnAnswer_Click method, but not with the frmView_Load method. I know I can just put the style info into div tag when I create it (this does work), but why doesn't the code above work?

Update:
I found something that may be going in the right direction. If I call webBrowser1.Update() at any point after webBrowser1.Navigate("about:blank") everything in frmView_Load works. Unfortunately, any attempts to change the document after frmView_Load exits will fail. Not only will they fail, but after frmView_Load returns webBrowser1.Document will be set to NULL somehow. Can anyone shed some light on how this control is supposed to work?


回答1:


After reviewing the MS Documentation on the WebBrowser control, I realize that everything the browser does is asynchronous. Having said that, it means that I have to block my control threads after setting properties in order to ensure those properties have been set.

Basically, my "write" to the document isn't done just because the "write" function returns. I have to block the control thread till the document reflects those changes if I want to reference the contents of that write. MS recommends a sleep loop. Here's what my write & block function looks like:

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

Thanks for your responses everyone.




回答2:


Why don't you put your hidden text in a <div> with the display:none style? When you need to show it, you'd just need to update the display style. You can also apply this style to the h2 element that contains your answer in your sample code.




回答3:


Im not really familiar with this stuff but I would have thought that you need to call

webBrowser1.Refresh();

at the very end of frmView_Load



来源:https://stackoverflow.com/questions/9527927/webbrowser-control-and-getelement-by-id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!