0

我有一个带有选项卡控件的桌面应用程序(表单),我分配了一个选项卡和一个新的自定义 webbrowser 控件。我打开了大约 10 个这样的选项卡。每个人访问大约 100 - 500 个不同的页面。

问题在于,如果 1 个网络浏览器控件出现问题,它会关闭整个程序。

我希望能够关闭有问题的 webbrowser 控件并在其位置打开一个新控件。

是否有任何事件需要我订阅才能捕获崩溃或无响应的网络浏览器控件?

我在 Windows 7(窗体)、.NET 框架 v4 上使用 C#

==================================================== ==============

更新:1 - 选项卡式 WebBrowser 示例

这是我拥有的代码以及我如何以最基本的方式使用 webbrowser 控件。

  1. 创建一个新的表单项目并将其命名为 SimpleWeb
  2. 添加一个新类并将其命名为 myWeb.cs,这是要使用的代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Policy;

namespace SimpleWeb
{
    //inhert all of webbrowser
    class myWeb : WebBrowser
    {

        public myWeb()
        {
            //no javascript errors
            this.ScriptErrorsSuppressed = true;

            //Something we want set?
            AssignEvents();
        }

        //keep near the top
        private void AssignEvents()
        {

            //assign WebBrowser events to our custom methods
            Navigated += myWeb_Navigated;
            DocumentCompleted += myWeb_DocumentCompleted;
            Navigating += myWeb_Navigating;
            NewWindow += myWeb_NewWindow;

        }


        #region Events
        //List of events:http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser_events%28v=vs.100%29.aspx

        //Fired when a new windows opens
        private void myWeb_NewWindow(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //cancel all popup windows
            e.Cancel = true;
            //beep to let you know canceled new window
            Console.Beep(9000, 200);
        }


        //Fired before page is navigated (not sure if its before or during?)
        private void myWeb_Navigating(object sender, System.Windows.Forms.WebBrowserNavigatingEventArgs args)
        {

        }

        //Fired after page is navigated (but not loaded)
        private void myWeb_Navigated(object sender, System.Windows.Forms.WebBrowserNavigatedEventArgs args)
        {

        }


        //Fired after page is loaded (Catch 22 - Iframes could be considered a page, can fire more than once. Ads are good examples)
        private void myWeb_DocumentCompleted(System.Object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs args)
        {

        }


        #endregion



        //Answer supplied by mo. (modified)?
        public void OpenUrl(string url)
        {
            try
            {
                //this.OpenUrl(url);
                this.Navigate(url);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Your App Crashed! Because = " + ex.ToString());
                //MyApplication.HandleException(ex);
            }
        }



        //Keep near the bottom
        private void RemoveEvents()
        {
            //Remove Events
            Navigated -= myWeb_Navigated;
            DocumentCompleted -= myWeb_DocumentCompleted;
            Navigating -= myWeb_Navigating;
            NewWindow -= myWeb_NewWindow;
        }
    }
}
  1. 在 Form1 上拖动标准 tabControl 并将停靠栏设置为填充,您可以进入选项卡集合并根据需要删除预填充的选项卡。

  2. 右键单击 Form1 并选择“查看代码”并将其替换为此代码。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using mshtml;

namespace SimpleWeb
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();


            //Load Up 10 Tabs
            for (int i = 0; i <= 10; i++)
            {
                newTab("Test_" + i, "http://wwww.yahoo.com");

            }
        }


        private void newTab(string Title, String Url)
        {

            //Create a new Tab
            TabPage newTab = new TabPage();
            newTab.Name = Title;
            newTab.Text = Title;

            //create webbrowser Instance
            myWeb newWeb = new myWeb();

            //Add webbrowser to new tab
            newTab.Controls.Add(newWeb);
            newWeb.Dock = DockStyle.Fill;

            //Add New Tab to Tab Pages
            tabControl1.TabPages.Add(newTab);

            newWeb.OpenUrl(Url);


        }
    }
}

保存并运行项目。

使用下面的答案。,您可以毫无问题地浏览第一个网址,但是用户点击的所有网址呢?我们如何检查这些?

我不喜欢向页面上的每个 html 元素添加事件,必须有一种方法可以在导航之前通过函数 OpenUrl 运行新的 url,而不会出现无限循环。

谢谢。

4

1 回答 1

2

您可以使用AppDomain.UnhandledExceptionorApplication.ThreadException事件。

但是以这种方式处理异常可能最终导致您的应用程序处于无效状态

您能否描述一下,这些异常何时发生。
它们是执行方法的结果吗?

那么在调用方法中处理错误会好得多。

void OpenUrl(Url url)
{
   try
   {
       var webBrowser = GetWebBrowser(tabControl.SelectedTab);
       webBrowser.OpenUrl(url);
   }
   catch(SpecificException ex)
   {
       MyApplication.HandleException(ex);
   }
}

关于你的评论,试试这个:

try
{
   myCustomWebbrowser.Navigate("yahoo.com");
}
catch(Exception ex) //catch specific exceptions here (catch all is a bad practice)
{
   MessageBox.Alert(ex.Message); //just for testing.
}

这篇文章应该可以帮助你:

private void AssignEvents()
{
  Navigated += myWeb_Navigated;
  DocumentCompleted += myWeb_DocumentCompleted;
  Navigating += myWeb_Navigating;
  NewWindow += myWeb_NewWindow;
  DownloadComplete += myWen_DownloadComplete;
}

void myWen_DownloadComplete(object sender, EventArgs e)
{
  // Check wheter the document is available (it should be)
  if (Document != null)
    // Subscribe to the Error event
    Document.Window.Error += myWeb_Window_Error;
}

void myWeb_Window_Error(object sender, HtmlElementErrorEventArgs e)
{
  // We got a script error, record it
  ScriptErrorManager.Instance.RegisterScriptError(e.Url, 
                           e.Description, e.LineNumber);
  // Let the browser know we handled this error.
  e.Handled = true;
}
于 2012-09-01T21:25:01.870 回答