Sto cercando di trovare un modo per il mio programma di sapere quando un web browser sta navigando e quando non lo è. Questo perché il programma interagirà con il documento caricato tramite JavaScript che verrà iniettato nel documento. Non ho alcun altro modo per sapere quando inizia la navigazione che gestire l'evento Navigating poiché non è il mio programma ma l'utente che naviga interagendo con il documento. Ma poi, quando si verifica DocumentCompleted
, non significa necessariamente che ha terminato la navigazione. Sono stato googling molto e trovato due pseudo-soluzioni:È possibile sapere con certezza se un web browser sta navigando o no?
Verificare la presenza di proprietà di WebBrowser ReadyState in caso
DocumentCompleted
. Il problema con questo è che se non viene caricato il documento ma viene caricato un frame nel documento, loReadyState
saràCompleted
anche se il documento principale non è completo.Per evitare questo, consigliano di vedere se il parametro Url passato al
DocumentCompleted
corrisponde al Url delWebBrowser
. In questo modo vorrei sapere cheDocumentCompleted
non viene invocato da qualche altro frame nel documento.
Il problema 2 è che, come ho detto, l'unico modo che ho per sapere quando una pagina sta navigando è gestendo l'evento Navigating
(o Navigated
). Quindi, se, ad esempio, sono su Google Maps e faccio clic su Cerca, verrà chiamato il numero Navigating
, ma solo una cornice sta navigando; non tutta la pagina (nello specifico caso di Google, potrei usare la proprietà TargetFrameName
di WebBrowserNavigatingEventArgs
per verificare se si tratta di un frame che sta navigando, ma i frame non hanno sempre nomi). Quindi, verrà chiamato DocumentCompleted
, ma non con la stessa Url
come la mia proprietà Url
Url
perché era solo una cornice quella che navigava, quindi il mio programma sarebbe la cosa che sta ancora navigando, per sempre.
L'aggiunta di chiamate a Navigating
e la sottrazione di chiamate a DocumentCompleted
non funziona. Non sono sempre gli stessi. Non ho trovato una soluzione a questo problema già da mesi; Ho utilizzato le soluzioni 1 e 2 e spero che funzionino nella maggior parte dei casi. Il mio piano era quello di utilizzare un timer nel caso in cui alcune pagine web avessero errori o qualcosa del genere, ma non credo che Google Maps abbia errori. Potrei ancora usarlo ma l'unica soluzione più brutta sarebbe quella di bruciare il mio PC.
Edit: Finora, questo è il più vicino che ho avuto modo di una soluzione:
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
eredita WebBrowser
. I metodi OnNavigating
, OnNavigated
e OnDocumentCompleted
vengono richiamati nei corrispondenti metodi sovrascritti WebBrowser
. La proprietà IsSafeNavigating
è quella che mi consente di sapere se sta navigando o meno.
Ma anche se JavaScript attiva una navigazione, verranno chiamati gli eventi 'Navigating' e' Navigated'. L'ho provato e ha funzionato in questo modo. Non capisco il tuo secondo paragrafo. Cosa intendi con "mentre vuoi fare qualcosa"? – Juan
@jsoldi ho paura che FrankJK sia sbagliato, se c'è una volontà, c'è un modo. si arriva a un riposo di 5 secondi dopo che l'intero documento è stato caricato per attendere la reindirizzamento di JavaScript, o per controllarli dopo che il documento è stato completato (controllando gli eventi) se uno è stato attivato o meno. In questo momento inserirò un messaggio su come superare alcuni dei tuoi ostacoli. –