尝试从TimerCallback访问webbrowser控件时C#“InvalidCastException”

时间:2012-01-28 21:45:11

标签: c# browser

基本上我和这个用户有同样的问题: How to check for TrackBar sliding with mouse hold and release 我使用提供的第一个解决方案解决了这个但是,当调用计时器时,我想在Web浏览器控件上调用InvokeScript。 InvokeScript运行时没有错误,但从不调用javascript函数。当我从按钮单击事件处理程序调用此脚本时,该函数被正确调用。

我发现当我尝试从webbrowser控件(如MessageBox.Show(webBrowser1.DocumentText))访问属性时,会抛出InvalidCastException。

// in constructor:
webBrowser1.AllowWebBrowserDrop = false;
webBrowser1.IsWebBrowserContextMenuEnabled = false;
webBrowser1.WebBrowserShortcutsEnabled = false;
webBrowser1.ObjectForScripting = this;
timer = new System.Threading.Timer(this.TimerElapsed);     

private void trackBar2_ValueChanged(object sender, EventArgs e)
{
        timer.Change(500, -1);
}
private void TimerElapsed(object state)
{
    this.webBrowser1.InvokeScript("jmp_end");
    MessageBox.Show(this.webBrowser1.DocumentText);
    timerRunning = false;
}
private void TimerElapsed(object state)
{
    WebBrowser brw = getBrowser();
    brw.Document.InvokeScript("jmpend");
    MessageBox.Show(brw.DocumentText);
    timerRunning = false;
}

有谁知道我在做错了什么?或者是否有其他方法可以获得相同的结果?

关于InvokeRequired的评论之后,这听起来就像我需要的......但是我无法让它工作..这是我从C# System.InvalidCastException

的示例代码中得到的
public delegate WebBrowser getBrowserHandler();
public WebBrowser getBrowser()
{
    if (InvokeRequired)
    {
        return Invoke(new getBrowserHandler(getBrowser)) as WebBrowser;
    }
    else
    {
        return webBrowser1;
    }
}

private void TimerElapsed(object state)
{
    WebBrowser brw = getBrowser();
    brw.Document.InvokeScript("jmpend");
    MessageBox.Show(brw.DocumentText);
    timerRunning = false;
}

我在这里错过了什么?

2 个答案:

答案 0 :(得分:6)

调用者(计时器)与创建控件的线程不同。

请参阅Control.InvokeRequired Property

应该解决您的问题的示例代码发布在这个问题上:C# System.InvalidCastException

答案 1 :(得分:2)

我遇到了同样的问题。正如Kevin P. Rice指出的那样,调用者处于一个不同于创建控件的线程上。一个简单的解决方案是每次线程需要与控件交互时使用this.Invoke(),因此,如果您希望让浏览器调用脚本,并且您希望从单独的线程内部调用它,那么只需执行此操作它是这样的:

this.Invoke(new Action(() => { brw.Document.InvokeScript("jmpend"); }));

或者,如果您希望更改窗体中浏览或其他控件的属性:

this.Invoke(new Action(() => { button1.Enabled = false; }));

如果您的主题声明在另一个范围内而不是您的表单,并且您不能使用this关键字,则需要找到一种方法来引用该表单的当前实例。

我希望这会有所帮助。 :)

相关问题