C# WPF - 等待页面加载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21095900/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# WPF - Waiting for page to load
提问by user3175176
I have seen several threads on StackOverflow concerning this topic, however none of them seem to provide an answer.
我在 StackOverflow 上看到了几个关于这个主题的线程,但是它们似乎都没有提供答案。
I have a button that, when clicked, opens up an invisible web page, navigates to a URL, enters information into a box, presses a button, and then scrapes the screen for information.
我有一个按钮,当点击它时,会打开一个不可见的网页,导航到一个 URL,在一个框中输入信息,按下一个按钮,然后在屏幕上抓取信息。
The bones of my code basically in the click:
我的代码的骨架基本上在点击:
WebBrowser wb = new WebBrowser;
wb.Visibility = System.Windows.Visibility.Hidden;
wb.Navigate("http://somepage.com");
And this is where it gets tricky.
这就是它变得棘手的地方。
I am looking for a way to ensurethat the page is loaded before trying to enter data or scrape the screen. I have seen several threads that talk about Navigated, IsLoaded, LoadCompletedas well as BackgroundWorkstuff, but I cannot get any of these to work.
我正在寻找一种方法来确保在尝试输入数据或抓取屏幕之前加载页面。我见过几个线程说说Navigated,IsLoaded,LoadCompleted以及BackgroundWork东西,但我不能让任何这些工作。
Which is the best option to use to determine that the page has fully loaded? How would you get the chosen method to work?
哪个是用于确定页面已完全加载的最佳选项?您将如何使所选方法发挥作用?
I also cannot get the data from the screen as WPF does not use the same GetElementByID.
我也无法从屏幕获取数据,因为 WPF 不使用相同的GetElementByID.
Edit:
编辑:
Per the comment below, here are the errors I run into:
根据下面的评论,这是我遇到的错误:
- Navigated first as soon as the page has been navigated too and does not necessarily wait until all objects are loaded. This works as intended, but cannot be used for my purposes.
IsLoadednever returns trueprivate void GetData_Click(object sender, RoutedEventArgs e) { int x=0; HTMLDocument doc; wb = new WebBrowser(); wb.Visibility = System.Windows.Visibility.Visible; wb.Navigate("somesite.com"); doc = wb.Document as mshtml.HTMLDocument; while(!wb.IsLoaded) { //Wait } doc.getElementById("txt_One").innerText = "It Worked"; }
- 一旦页面也被导航,就首先导航,不一定要等到所有对象都加载完毕。这按预期工作,但不能用于我的目的。
IsLoaded从不返回真private void GetData_Click(object sender, RoutedEventArgs e) { int x=0; HTMLDocument doc; wb = new WebBrowser(); wb.Visibility = System.Windows.Visibility.Visible; wb.Navigate("somesite.com"); doc = wb.Document as mshtml.HTMLDocument; while(!wb.IsLoaded) { //Wait } doc.getElementById("txt_One").innerText = "It Worked"; }
Puts it in an infinite loop as wbdoes not ever seem to load.
将其置于无限循环中,因为wb似乎从未加载过。
- This is the version with LoadCompleted
- 这是带有 LoadCompleted 的版本
The event 'System.Windows.Controls.WebBrowser.LoadCompleted' can only appear on the left hand side of += or -=
事件“System.Windows.Controls.WebBrowser.LoadCompleted”只能出现在 += 或 -= 的左侧
private void GetData_Click(object sender, RoutedEventArgs e)
{
int x=0;
HTMLDocument doc;
wb = new WebBrowser();
wb.Visibility = System.Windows.Visibility.Visible;
wb.Navigate("somesite.com");
doc = wb.Document as mshtml.HTMLDocument;
wb.LoadCompleted += wb_LoadCompleted;
doc.getElementById("txt_One").innerText = "It Worked";
}
void wb_LoadCompleted(object sender, NavigationEventArgs e)
{
}
Produces the error
产生错误
An unhandled exception of type 'System.NullReferenceException' occured in {filename}
Additional information: Object reference not set to an instance of an object.
{filename} 中发生类型为“System.NullReferenceException”的未处理异常
附加信息:未将对象引用设置为对象的实例。
回答by user2453734
The webbrowser control has a loadedevent (which you have): LoadCompleted: fires when the dom is fully loaded.
webbrowser 控件有一个加载事件(你有): LoadCompleted: 当 dom 完全加载时触发。
Bind the event and in the event method get the document instead of right away.
绑定事件并在事件方法中获取文档而不是立即获取。
//root is a grid element identified in the XAML
public WebBrowser webb;
public MainWindow()
{
InitializeComponent();
webb = new WebBrowser();
webb.Visibility = System.Windows.Visibility.Hidden;
root.Children.Add(webb);
webb.LoadCompleted += webb_LoadCompleted;
webb.Navigate("http://www.google.com");
}
void webb_LoadCompleted(object sender, NavigationEventArgs e)
{
MessageBox.Show("Completed loading the page");
mshtml.HTMLDocument doc = webb.Document as mshtml.HTMLDocument;
mshtml.HTMLInputElement obj = doc.getElementById("gs_taif0") as mshtml.HTMLInputElement;
mshtml.HTMLFormElement form = doc.forms.item(Type.Missing, 0) as mshtml.HTMLFormElement;
webb.LoadCompleted -= webb_LoadCompleted; //REMOVE THE OLD EVENT METHOD BINDING
webb.LoadCompleted += webb_LoadCompleted2; //BIND TO A NEW METHOD FOR THE EVENT
obj.value = "test search";
form.submit(); //PERFORM THE POST ON THE FORM OR SEARCH
}
//SECOND EVENT TO FIRE AFTER YOU POST INFORMATION
void webb_LoadCompleted2(object sender, NavigationEventArgs e)
{
MessageBox.Show("Completed loading the page second time after post");
}
You need to do doc = wb.Document as mshtml.HTMLDocument; in the loadcompleted event. Because until the load is complete you cannot get the document.
你需要做 doc = wb.Document 作为 mshtml.HTMLDocument; 在 loadcompleted 事件中。因为在加载完成之前您无法获得文档。

