Я пытаюсь найти способ для моей программы знать, когда WebBrowser выполняет навигацию, а когда нет. Это связано с тем, что программа будет взаимодействовать с загруженным документом через JavaScript, который будет внедрен в документ. Я не У меня нет другого способа узнать, когда он начинает навигацию, кроме обработки события Navigating , поскольку это не моя программа, а пользователь, который будет осуществлять навигацию, взаимодействуя с документом. Но тогда, когда возникает DocumentCompleted
, это не обязательно означает, что навигация завершена. Я много искал в Google и нашел два псевдорешения:
Проверьте свойство WebBrowser ReadyState в событии DocumentCompleted
. Проблема в том, что если загружается не документ, а фрейм в документе, ReadyState
будет Завершено
, даже если основной документ не завершен.
Чтобы предотвратить это , они советуют проверить, совпадает ли параметр URL , переданный в DocumentCompleted
, URL URL WebBrowser
. Таким образом, я бы знал, что DocumentCompleted
не вызывается каким-либо другим фреймом в документе.
Проблема с 2 в том, что, как я сказал, единственный способ узнать, когда страница навигация осуществляется путем обработки события Navigating
(или Navigated
). Так, если, например, я нахожусь в Картах Google и нажимаю «Поиск», будет вызываться 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
- это то свойство, которое сообщит мне, перемещается оно или нет.