我有一个带有WebBrowser控件的表单,还有一个单独的线程来控制浏览器并等待其加载。这是一个代码示例:

private void Form1_Load(object sender, EventArgs e){
    JobClass.mainAsync();
}


--

public static class JobClass
{
    public static void mainAsync()
    {
        Thread t = new Thread(main);
        t.Start();
    }

    private static void main()
    {
        Form1 frm = (Form1)Application.OpenForms["Form1"];
        WebBrowser wb = frm.webBrowser1;

        gotoGoogle(frm, wb);
    }

    private static void gotoGoogle(Form1 frm, WebBrowser wb)
    {
        frm.Invoke((MethodInvoker)delegate
        {
            wb.Navigate("google.com");
            string loc = wb.Document.Url.AbsolutePath;
            // ... some extra code ...
        });
    }

    private static void gotoYoutube(Form1 frm, WebBrowser wb)
    {
        frm.Invoke((MethodInvoker)delegate
        {
            wb.Navigate("youtube.com");
            wb.Document.Body.getElementById("...");
            // ... some extra code ...
        });
    }

}


一切运行正常,但是正如您所看到的,我必须将Form1变量传递给处理浏览器控件的每个方法,并且必须在所有方法中都编写frm.Invoke(),这使得我的代码不那么可移植,而且痛苦更大。代码变得更大。

我想知道是否可以在“ main()”方法内做一些事情,使WebBrowser可能是同一线程的子代,所以我不必每次都从表单中调用它吗?如果不是,我该如何摆脱这个丑陋的调用东西?

最佳答案

您可以执行以下操作


在JobClass中定义一个事件,将其称为OnNavigationChanged
在您的Form1中处理事件引发
在已处理事件方法中,可以调用wb.Navigate(url);。


这里是示例代码

1- JobClass委托

//在JobClass上方定义此委托

public delegate void JobClassNavigationEvent(string url);


2-定义事件

public delegate void JobClassNavigationEvent(string url);
public static class JobClass
{
    public static event JobClassNavigationEvent OnNavigationChanged;
    private static BackgroundWorker worker;
    public static void mainAsync()
    {
        worker = new BackgroundWorker();
        worker.DoWork += (s, e) =>
        {
            main();
        };
        worker.RunWorkerAsync();
    }

    private static void main()
    {
        gotoGoogle();
    }

    private static void gotoGoogle()
    {
        if (OnNavigationChanged != null)
            OnNavigationChanged.Invoke("google.com");
    }

    private static void gotoYoutube()
    {
        if (OnNavigationChanged != null)
            OnNavigationChanged.Invoke("youtube.com");
    }
}


3-以您的形式

private void Form1_Load(object sender, EventArgs e){
    JobClass.OnNavigationChanged+=(url)=>{
       webBrowser1.Navigate(url);
       // other code come here
    };
    JobClass.mainAsync();
}


希望能帮到你

关于c# - 在不使用C#中访问调用的情况下访问控件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26904782/

10-17 02:06