Estoy tratando de encontrar una forma para que mi programa sepa cuándo navega WebBrowser y cuándo no. Esto se debe a que el programa interactuará con el documento cargado a través de JavaScript que se inyectará en el documento. No tengo otra forma de saber cuándo comienza a navegar que manejar el evento Navigating ya que no es mi programa sino el usuario que navegará al interactuar con el documento. Pero luego, cuando ocurre DocumentCompleted
, no necesariamente significa que ha terminado de navegar. He estado buscando en Google mucho y encontré dos pseudo-soluciones:¿Es posible saber con certeza si un WebBrowser está navegando o no?
Comprobar si ReadyState propiedad de WebBrowser en caso
DocumentCompleted
. El problema con esto es que si no se carga el documento sino un marco en el documento, elReadyState
seráCompleted
incluso si el documento principal no se completa.Para evitar esto, se aconsejan para ver si el parámetro pasado a Url
DocumentCompleted
coincide con el Url delWebBrowser
. De esta manera sabría queDocumentCompleted
no está siendo invocado por algún otro marco en el documento.
El problema con 2 es que, como ya he dicho, la única forma que tengo de saber cuando una página está navegando es por el manejo del evento Navigating
(o Navigated
). Entonces, si, por ejemplo, estoy en Google Maps y hago clic en Buscar, se llamará al Navigating
, pero solo está navegando un marco; no toda la página (en el caso específico de Google, podría usar la propiedad TargetFrameName
de WebBrowserNavigatingEventArgs
para verificar si es un marco el que está navegando, pero los marcos no siempre tienen nombres). Así que después de eso, se llamará DocumentCompleted
, pero no con la misma Url
como mi propiedad WebBrowser
s Url
porque era solo un marco el que navegaba, por lo que mi programa querría que siga navegando, para siempre.
Agregar llamadas a Navigating
y restar llamadas a DocumentCompleted
tampoco funcionará. No son siempre lo mismo. No he encontrado una solución a este problema desde hace meses; He estado usando las soluciones 1 y 2 y espero que funcionen en la mayoría de los casos. Mi plan era usar un temporizador en caso de que alguna página web tenga errores o algo así, pero no creo que Google Maps tenga ningún error. Todavía podría usarlo, pero la única solución más fea sería quemar mi PC.
Editar: Hasta ahora, esto es lo más cercano que tengo a una solución:
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
hereda WebBrowser
. Se invocan los métodos OnNavigating
, OnNavigated
y OnDocumentCompleted
en los métodos reemplazados WebBrowser
correspondientes. La propiedad IsSafeNavigating
es la que me avisaría si está navegando o no.
Pero incluso si javascript desencadena una navegación, '' Navigating' y eventos Navigated' se llamará. Lo probé y funcionó de esta manera. No entiendo tu segundo párrafo. ¿A qué te refieres con "mientras quieres hacer algo"? – Juan
@jsoldi tengo miedo de que FrankJK esté equivocado, si hay voluntad, hay una manera. obtiene un descanso de 5 segundos después de que todo el documento se haya cargado para esperar a que se redirija el código de JavaScript o lo busca después de completar el documento (mediante la comprobación de eventos) si uno se activa o no. Voy a (ahora mismo) publicar un mensaje sobre cómo puede superar algunos de sus obstáculos. –