Я пытаюсь найти способ, чтобы моя программа знала, когда веб-браузер выполняет навигацию, а когда нет. Это связано с тем, что программа будет взаимодействовать с загруженным документом через JavaScript, который будет внедрен в документ. У меня нет другого способа узнать, когда начинается навигация, кроме обработки Навигация, так как это не моя программа, а пользователь, который будет перемещаться, взаимодействуя с документом. Но тогда, когда происходит DocumentCompleted
, это не обязательно означает, что навигация завершена. Я много гуглил и нашел два псевдорешения:
Проверьте свойство WebBrowser ReadyState в
DocumentCompleted
событие. Проблема в том, что если загружается не документ, а фрейм в документе,ReadyState
будетCompleted
, даже если основной документ не завершен.Чтобы предотвратить это, они советуют проверить, соответствует ли URL параметр, переданный в
DocumentCompleted
, соответствует URL изWebBrowser
. Таким образом, я бы знал, чтоDocumentCompleted
не вызывается каким-либо другим фреймом в документе.
Проблема с 2 заключается в том, что, как я уже сказал, единственный способ узнать, когда страница находится в процессе навигации, — это обработать событие Navigating
(или Navigated
). Так что, если, например, я нахожусь в Google Maps и нажимаю «Поиск», будет вызываться Navigating
, но навигация происходит только по фрейму; не вся страница (в конкретном случае с Google я мог бы использовать свойство TargetFrameName
WebBrowserNavigatingEventArgs
, чтобы проверить, является ли фрейм тем, по которому осуществляется навигация, но у фреймов не всегда есть имена). Итак, после этого будет вызываться DocumentCompleted
, но не с тем же Url
, что и мое свойство WebBrowser
s Url
, потому что это был просто фрейм, который перемещался, поэтому моя программа думала, что она все еще перемещается, навсегда.
Добавление вызовов к Navigating
и вычитание вызовов к DocumentCompleted
также не сработает. Они не всегда одинаковы. Я не могу найти решение этой проблемы уже несколько месяцев; Я использовал решения 1 и 2 и надеюсь, что они будут работать в большинстве случаев. Мой план состоял в том, чтобы использовать таймер на случай, если на какой-то веб-странице есть ошибки или что-то в этом роде, но я не думаю, что у Google Maps есть какие-либо ошибки. Я все еще мог бы использовать его, но единственным более уродливым решением было бы сжечь мой компьютер.
Редактировать: На данный момент это самое близкое решение, которое у меня есть:
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
— это то, что даст мне знать, перемещается оно или нет.