【发布时间】:2010-11-08 19:44:22
【问题描述】:
我正在尝试找到一种方法让我的程序知道 WebBrowser 何时正在导航,何时不是。这是因为程序将通过将注入文档的 JavaScript 与加载的文档进行交互。除了处理Navigating 事件之外,我没有其他方法可以知道它何时开始导航,因为不是我的程序,而是将通过与文档交互进行导航的用户。但是,当DocumentCompleted 出现时并不一定意味着它已经完成导航。我一直在谷歌搜索,发现了两个伪解决方案:
在
DocumentCompleted事件中检查 WebBrowser 的 ReadyState 属性。这样做的问题是,如果加载的不是文档而是文档中的一个框架,即使主文档没有完成,ReadyState也将是Completed。为了防止这种情况,他们建议查看传递给
DocumentCompleted的Url 参数是否与WebBrowser的Url 匹配。这样我就知道DocumentCompleted没有被文档中的其他框架调用。
2 的问题在于,正如我所说,我必须知道页面何时导航的唯一方法是处理 Navigating(或 Navigated)事件。因此,例如,如果我在 Google 地图中并单击搜索,Navigating 将被调用,但只是一个框架正在导航;不是整个页面(在特定的 Google 案例中,我可以使用 WebBrowserNavigatingEventArgs 的 TargetFrameName 属性来检查它是否是正在导航的框架,但框架并不总是有名称)。所以在那之后,DocumentCompleted 将被调用,但与 Url 与我的 WebBrowsers Url 属性不同,因为它只是一个导航的框架,所以我的程序会认为它仍在导航,永远。
添加对Navigating 的调用并减去对DocumentCompleted 的调用也不起作用。它们并不总是相同的。我已经好几个月没有找到解决这个问题的方法了。我一直在使用解决方案 1 和 2,并希望它们适用于大多数情况。我的计划是使用计时器以防某些网页出现错误或其他情况,但我认为 Google 地图没有任何错误。我仍然可以使用它,但唯一更糟糕的解决方案是烧毁我的电脑。
编辑:到目前为止,这是我最接近解决方案的:
partial class SafeWebBrowser
{
private class SafeNavigationManager : INotifyPropertyChanged
{
private SafeWebBrowser Parent;
private bool _IsSafeNavigating = false;
private int AccumulatedNavigations = 0;
private bool NavigatingCalled = false;
public event PropertyChangedEventHandler PropertyChanged;
public bool IsSafeNavigating
{
get { return _IsSafeNavigating; }
private set { SetIsSafeNavigating(value); }
}
public SafeNavigationManager(SafeWebBrowser parent)
{
Parent = parent;
}
private void SetIsSafeNavigating(bool value)
{
if (_IsSafeNavigating != value)
{
_IsSafeNavigating = value;
OnPropertyChanged(new PropertyChangedEventArgs("IsSafeNavigating"));
}
}
private void UpdateIsSafeNavigating()
{
IsSafeNavigating = (AccumulatedNavigations != 0) || (NavigatingCalled == true);
}
private bool IsMainFrameCompleted(WebBrowserDocumentCompletedEventArgs e)
{
return Parent.ReadyState == WebBrowserReadyState.Complete && e.Url == Parent.Url;
}
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null) PropertyChanged(this, e);
}
public void OnNavigating(WebBrowserNavigatingEventArgs e)
{
if (!e.Cancel) NavigatingCalled = true;
UpdateIsSafeNavigating();
}
public void OnNavigated(WebBrowserNavigatedEventArgs e)
{
NavigatingCalled = false;
AccumulatedNavigations++;
UpdateIsSafeNavigating();
}
public void OnDocumentCompleted(WebBrowserDocumentCompletedEventArgs e)
{
NavigatingCalled = false;
AccumulatedNavigations--;
if (AccumulatedNavigations < 0) AccumulatedNavigations = 0;
if (IsMainFrameCompleted(e)) AccumulatedNavigations = 0;
UpdateIsSafeNavigating();
}
}
}
SafeWebBrowser 继承 WebBrowser。方法OnNavigating、OnNavigated 和OnDocumentCompleted 在相应的WebBrowser 覆盖方法上调用。 IsSafeNavigating 的属性会让我知道它是否正在导航。
【问题讨论】:
标签: c# .net browser webbrowser-control