Jua*_*uan 7 .net c# browser webbrowser-control
我正试图找到一种方法让我的程序知道WebBrowser何时导航以及何时不导航.这是因为程序将通过将在文档中注入的JavaScript与加载的文档进行交互.我没有任何其他方式知道它何时开始导航而不是处理导航事件,因为不是我的程序,而是将通过与文档交互进行导航的用户.但是,当DocumentCompleted发生时并不一定意味着它已完成导航.我一直在谷歌搜索,发现两个伪解决方案:
在事件中检查WebBrowser的ReadyState属性DocumentCompleted.这里的问题是,如果没有这个文件,但该文件加载的框架中,ReadyState将Completed即使没有完成主文档.
为了防止这种情况,他们建议,看是否网址参数传递到DocumentCompleted比赛地址的WebBrowser.这样我就会知道DocumentCompleted文档中的某些其他框架没有调用它.
2的问题在于,正如我所说,我必须知道页面导航的唯一方法是处理Navigating(或Navigated)事件.因此,例如,如果我在Google地图中并点击搜索,Navigating则会调用,但只是一个框架正在导航; 不是整个页面(在特定的Google案例中,我可以使用TargetFrameName属性WebBrowserNavigatingEventArgs来检查它是否是正在导航的帧,但帧并不总是有名称).所以在那之后,DocumentCompleted将被调用,但不会与Url我WebBrowser的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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
SafeWebBrowser继承WebBrowser.方法OnNavigating,OnNavigated并OnDocumentCompleted在相应的WebBrowser重写方法上调用.该物业IsSafeNavigating是让我知道它是否正在导航的物业.
首先,我将文档转换为 XML,然后使用我的神奇方法:
nodeXML = HtmlToXml.ConvertToXmlDocument((IHTMLDocument2)htmlDoc.DomDocument);
if (ExitWait(false))
return false;
Run Code Online (Sandbox Code Playgroud)
转换:
public static XmlNode ConvertToXmlDocument(IHTMLDocument2 doc2)
{
XmlDocument xmlDoc = new XmlDocument();
IHTMLDOMNode htmlNodeHTML = null;
XmlNode xmlNodeHTML = null;
try
{
htmlNodeHTML = (IHTMLDOMNode)((IHTMLDocument3)doc2).documentElement;
xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", ""/*((IHTMLDocument2)htmlDoc.DomDocument).charset*/, ""));
xmlNodeHTML = xmlDoc.CreateElement("html"); // create root node
xmlDoc.AppendChild(xmlNodeHTML);
CopyNodes(xmlDoc, xmlNodeHTML, htmlNodeHTML);
}
catch (Exception err)
{
Utils.WriteLog(err, "Html2Xml.ConvertToXmlDocument");
}
Run Code Online (Sandbox Code Playgroud)
魔术方法:
private bool ExitWait(bool bDelay)
{
if (m_bStopped)
return true;
if (bDelay)
{
DateTime now = DateTime.Now;
DateTime later = DateTime.Now;
TimeSpan difT = (later - now);
while (difT.TotalMilliseconds < MainDef.IE_PARSER_DELAY)
{
Application.DoEvents();
System.Threading.Thread.Sleep(10);
later = DateTime.Now;
difT = later - now;
if (m_bStopped)
return true;
}
}
return m_bStopped;
}
Run Code Online (Sandbox Code Playgroud)
其中 m_bStopped 默认为 false,IE_PARSER_DELAY 是超时值。我希望这有帮助。
| 归档时间: |
|
| 查看次数: |
2548 次 |
| 最近记录: |