簡體   English   中英

嘗試從TimerCallback訪問webbrowser控件時C#“InvalidCastException”

[英]C# “InvalidCastException” when trying to access webbrowser control from TimerCallback

基本上我遇到與此用戶相同的問題: 如何使用鼠標保持和釋放檢查TrackBar滑動我使用提供的第一個解決方案修復了此問題。 但是,當調用計時器時,我想在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;
}

我錯過了什么?

調用者(計時器)與創建控件的線程不同。

請參見Control.InvokeRequired屬性

應該解決您的問題的示例代碼發布在這個問題上: C#System.InvalidCastException

我有同樣的問題。 正如Kevin P. Rice指出的那樣,調用者處於一個不同於創建控件的線程上。 一個簡單的解決方案是每次線程需要與控件交互時使用this.Invoke() ,因此,如果您希望讓瀏覽器調用腳本,並且您希望從單獨的線程內部調用它,只需執行此操作它是這樣的:

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

或者,如果您希望更改窗體中瀏覽或其他控件的屬性:

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

如果您的線程聲明在另一個范圍而不是表單的范圍內,並且您不能使用this關鍵字,則需要找到一種方法來引用表單的當前實例。

我希望這有幫助。 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM