2012-05-01 2 views
0

Я вступаю в WPF - впервые в (VB) .NET - и пытаюсь воссоздать проект, который я начал в MS Access VBA. Он в основном разбивает серию страниц в веб-приложении. Как вы могли догадаться, у меня возникают проблемы с событием LoadCompleted.Ожидание WebBrowser для полной загрузки между несколькими вызовами Navigate()

Я искал и нашел некоторую информацию об этом, но «поток» кода поддается только ожиданию загрузки одной страницы. Например:

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

Все исполнения кода выполняется в случае DocumentLoaded, который прекрасно работает, когда вам просто нужно перейти на одну страницу и выполнить код. Но мне нужно выполнить серию этих циклов для моего приложения.

Как я могу надежно дождаться, когда документ будет полностью загружен, сохраняя при этом выполнение кода в том же Sub и не блокируя поток пользовательского интерфейса?

Вот основная идея того, что я пытаюсь сделать.

  1. Перейдите на страницу
  2. Дождитесь страницы, чтобы полностью загрузить
  3. делать вещи
  4. Перейдите на страницу
  5. полоскание, Repeat

PS - .NET очень ново для меня поэтому, пожалуйста, не делайте мой мозг переполнением стекол;)

Thanks, Брайан

- ## EDIT ## -

Это то, что я использую, чтобы сделать в 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 существенно различаются.

ответ

1

Я бы просто позвонил Navigate еще раз в конце LoadCompleted. Затем, я думаю, используйте переменную с окном, чтобы отслеживать целевые 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); 
} 

EDIT

Может быть что-то вроде этого было бы более подходящим. После каждого цикла вы можете настроить следующий 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-адресов и сам URL-адрес динамически генерируются после каждого «цикла» – brian

+0

@brian. Разве это не было бы принципиально? Просто вызовите некоторую реализацию ** getNextUrl() ** и уходите? – McGarnagle

+0

Ах, я вижу. Вы говорите, что я могу добавлять элементы в список «на лету», поскольку я повторяю этот список. Но мои действия (код) для каждого URL-адреса разные. Я просто собираюсь иметь огромный SELECT..Case для обработки каждого URL-адреса? Поскольку я не знаю URL-адрес, пока он не станет следующей страницей в списке, как я могу сопоставить текущий URL-адрес браузеров с соответствующим кодом? Надеюсь, я задаю вопрос достаточно ясно. Я ценю, что вы предлагаете мне время, чтобы помочь. Спасибо. – brian

0

Может быть, я далеко, но я бы «делать вещи» в BackGroundWorker. Пусть основная нить ничего не делает, кроме поиска страниц. Если «делать вещи» медленнее, чем найти, затем найдите дроссельную заслонку.

Вы считали, что WebClient загружается в массив String или Byte, а затем преобразовывается в DOM. Что-то в IE вам нужно?

+0

Привет, Blam - «материал» в этом случае очищает данные от браузеров DOM. Я не вижу, как может помочь BGW. Независимо от того, какой поток на нем работает, все равно нужно дождаться полной загрузки IE. Чтобы сделать несколько вызовов в WebBrowser и все это выгрузиться в обработчике событий, это создает для меня вызов. – brian

+0

@brian См. Обновленный ответ. Если вы не видите, как это может сделать материал на BGW, я сомневаюсь, что смогу вам помочь. – Paparazzi

+0

Возможно, я просто не понимаю, что вы предлагаете? У меня 5 дней в .NET. Таким образом, в событии нажатия кнопки я заказываю его для перехода на страницу. Затем «запустите» BGW, чтобы прочитать dom страницы. Я все еще придерживаюсь той же проблемы. Я не могу начать чтение DOM, пока браузер не завершит загрузку. Нельзя одновременно делать две вещи. Он делает одно и получает подтверждение, что он завершился, прежде чем перейти к следующему, а затем промыть/повторить. Я бы предпочел не блокировать мое приложение в этом процессе, но в этот момент мне все равно, если это означает, что он должен делать то, что я хочу. – brian