我正在使用 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}
请注意,我可以使用 btnAnswer_Click 方法控制 Style 属性,但不能使用 frmView_Load 方法。我知道我可以在创建它时将样式信息放入 div 标签中(这确实有效),但为什么上面的代码不起作用?
更新:
我发现一些事情可能正在朝着正确的方向发展。如果我在 webBrowser1.Navigate("about:blank")
之后的任何时候调用 webBrowser1.Update()
,frmView_Load 中的所有内容都会起作用。不幸的是,在 frmView_Load 退出后任何更改文档的尝试都将失败。它们不仅会失败,而且在 frmView_Load 返回后,webBrowser1.Document 将以某种方式设置为 NULL。
谁能解释一下这个控件应该如何工作?
最佳答案
在查看了有关 WebBrowser 控件的 MS 文档后,我意识到浏览器所做的一切都是异步的。话虽如此,这意味着我必须在设置属性后阻止我的控制线程,以确保这些属性已被设置。
基本上,我对文档的“写入”并不仅仅因为“写入”函数返回而完成。如果我想引用该写入的内容,我必须阻塞控制线程,直到文档反射(reflect)这些更改。 MS 建议使用 sleep 循环。这是我的写入和阻止函数的样子:
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;
}
}
感谢大家的回复。
关于c# - WebBrowser 控件和通过 ID 获取元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9527927/