2012-05-01 44 views
0

我正在冒险进入WPF - 第一次在(VB).NET中 - 并试图重新创建一个项目,我开始使用MS Access VBA。它基本上是在Web应用程序中删除一系列页面。正如你可能已经猜测,我有LoadCompleted事件的麻烦。等待WebBrowser在多个Navigate()调用之间完全加载

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

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

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

我该如何可靠地等待文档完全加载,同时仍然保持代码执行在同一个Sub中,而不是锁定UI线程?

下面是我想要做的一个基本想法。

  1. 导航页
  2. 为等待页面完全加载
  3. 做的东西
  4. 导航页
  5. 冲洗,重复

PS - .NET是非常新的我所以请不要让我的大脑堆栈溢出;)

谢谢, 布赖恩

- ##编辑## -

这是我用VBA做。这正是我想要做的,只是在“.NET”的方式,而不会阻止用户界面主题:

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的交互显着不同。

回答

1

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

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); 
} 
+0

dbaseman,谢谢你的回复。不幸的是,我正在浏览的网址并不知道。换句话说,所需的URL数量和URL本身是在每个“循环”后都会动态生成的 – brian

+0

@brian gotcha。原则上不是这样吗?只需调用** getNextUrl()**的一些实现并离开你去? – McGarnagle

+0

啊,我明白了。你说我可以在列表中添加项目,因为我正在迭代列表。但是我对每个URL的操作(代码)是不同的。我只是要有一个巨大的SELECT..Case来处理每个URL?由于直到列表中的下一页才知道URL,因此如何将浏览器当前URL与适当的代码块进行匹配?我希望我能够清楚地问这个问题。我感谢你给我你的时间来帮助。谢谢。 – brian

0

也许我走了,但我会“做东西”在BackGroundWorker。让主线程不做任何事情,但找到页面。如果“做东西”比查找慢,然后找到下一个油门。

您是否考虑WebClient下载到字符串或字节数组,然后转换为DOM。你需要IE吗?

+0

嗨Blam - 在这种情况下的“东西”是从浏览器DOM中抓取数据。我看不到BGW如何提供帮助。无论它运行什么线程,都需要等待IE完全加载。不得不对WebBrowser进行多次调用,并将其全部转储到事件处理函数中,这对我来说是一个挑战。 – brian

+0

@brian查看更新的答案。如果你看不到BGW上的东西会如何帮助,那么我怀疑我可以帮助你。 – Paparazzi

+0

也许我只是不明白你的建议?我进入.NET 5天。所以在按钮的点击事件中,我编码它以导航到页面。然后“运行”一个BGW来阅读页面的dom。我仍然坚持同样的问题。在浏览器完成加载之前,我无法开始阅读DOM。这不是同时做两件事的问题。它正在做一件事,并在我转向下一件事之前得到确认,然后冲洗/重复。我不想在程序中锁定我的应用程序,但在这一点上,我甚至不在乎它是否意味着让它做我想做的事情。 – brian

相关问题