等待WebBrowser在多个Navigate()调用之间完全加载

时间:2012-05-01 13:56:30

标签: .net wpf vb.net user-controls webbrowser-control

我正在冒险进入WPF - 第一次使用(VB).NET - 并尝试重新创建一个我在MS Access VBA中启动的项目。它基本上擦除了Web应用程序中的一系列页面。正如您可能猜测的那样,我遇到了LoadCompleted事件的问题。

我已经搜索并找到了一些信息,但代码的“流程”只能等待一页加载。例如:

http://social.msdn.microsoft.com/Forums/nn-NO/wpf/thread/52c1bc55-dd41-468c-8759-a42726635d4b

所有代码执行都在DocumentLoaded事件中运行,只需要导航到一个页面并执行代码就可以正常工作。但我需要为我的应用程序执行一系列这些循环。

我如何可靠地等待文档完全加载,同时仍然将代码执行保持在相同的Sub并且不锁定UI线程?

这是我想要做的基本想法。

  1. 导航到页面
  2. 等待页面完全加载
  3. 做东西
  4. 导航到页面
  5. 冲洗,重复
  6. P.S - .NET对我来说是一个新手,所以请不要让我的大脑出现堆栈溢出;)

    谢谢, 布赖恩

    - ##编辑## -

    这是我在VBA中使用的方法。这正是我正在尝试做的,只是以“.NET”的方式,而没有阻止UI线程:

    Dim oIE = New SHDocVw.InternetExplorer
    
            With oIE
                .Navigate(strURL)
                .Visible = False
    
    
               ' loop until the page finishes loading
               Do While oIE.Busy : Loop
               Do While oIE.ReadyState <> 4 : Loop
    
               'Code goes here to read DOM, get fields and click a button (logging in to site)
               'My code execution is done and now I'm ready to go to the next page and read the DOM
    
               .Navigate(strURL)
    
            End With
    

    。 。 。

    就是这样。重复 n 次。我与每个DOM的交互有很大不同。

2 个答案:

答案 0 :(得分:1)

我只需在Navigate处理程序的末尾再次调用LoadCompleted。然后,我想,使用一个窗口范围的变量来跟踪您的目标网址。

List<string> _urls;
int _i = 0;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    _urls = new List<string>() { url1, url2, url3 };    // URLs to navigate
    webBrowser1.LoadCompleted += webBrowser1_LoadCompleted;
    webBrowser1.Navigate(_urls[_i]);
}
void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
{
    // do stuff

    i++;
    var nextUrl = _urls[i];
    webBrowser1.Navigate(nextUrl);
}

修改

也许这样的事情会更合适。在每个周期之后,您可以设置下一个URL及其处理程序。

class NavIteration
{
    public string Url { get; set; }
    public delegate void HandleResult(object sender, NavigationEventArgs e);
    public HandleResult ResultHandler { get; set; }
}

NavIteration CurrentIteration;

void setNextIteration()
{
    CurrentIteration = null;
    CurrentIteration = new NavIteration() { 
        Url = someurl, 
        ResultHandler = (sender, e) => {
            // handle
        }
    };
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    webBrowser1.LoadCompleted += webBrowser1_LoadCompleted;
    setNextIteration();
    webBrowser1.Navigate();
}

void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
{
    CurrentIteration.ResultHandler(sender, e);
    setNextIteration();
    webBrowser1.Navigate(CurrentIteration.Url);
}

答案 1 :(得分:0)

也许我离开了,但我会在BackGroundWorker中“做事”。让主线程除了查找页面之外什么也不做。如果“do stuff”比find更慢,那么下一步调整find。

您是否考虑过将WebClient下载到String或Byte数组,然后转换为DOM。你需要IE吗?