Можно ли точно узнать, выполняет ли WebBrowser навигацию или нет?

Я пытаюсь найти способ для моей программы знать, когда WebBrowser выполняет навигацию, а когда нет. Это связано с тем, что программа будет взаимодействовать с загруженным документом через JavaScript, который будет внедрен в документ. Я не У меня нет другого способа узнать, когда он начинает навигацию, кроме обработки события Navigating , поскольку это не моя программа, а пользователь, который будет осуществлять навигацию, взаимодействуя с документом. Но тогда, когда возникает DocumentCompleted , это не обязательно означает, что навигация завершена. Я много искал в Google и нашел два псевдорешения:

  1. Проверьте свойство WebBrowser ReadyState в событии DocumentCompleted . Проблема в том, что если загружается не документ, а фрейм в документе, ReadyState будет Завершено , даже если основной документ не завершен.

  2. Чтобы предотвратить это , они советуют проверить, совпадает ли параметр 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 - это то свойство, которое сообщит мне, перемещается оно или нет.

7
задан Juan 18 November 2010 в 20:11
поделиться