Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Web Browser in C#

0.00/5 (No votes)
20 Feb 2010 1  
A tabbed Web Browser in C# with favicons, History & Favorites, Links Bar, View Source, Search, and Print functionalities.

WBrowser.png

Contents

Introduction

This was my first project in C#. This article describes how to implement some of the features of a Web Browser application like managing tabs, viewing the favicon of a particular website, managing Favorites websites and Links Bar, viewing the History, searching on Google or Live Search, saving settings between application runs, viewing the source and properties of a website, printing the content of page, and others. C# has a WebBrowser control that does all the work of rendering web pages.

Implementing Tab functionality

In my main form, I added a TabControl control named browserTabControl with only one TabPage which represents the "New" tab. When the user clicks the "New" tab, then a new tab is created. The addNewTab() method shows how to add a new tab in your web browser.

private void addNewTab()
{
    // create a new TabPage object
    TabPage tpage = new TabPage(); 
    tpage.BorderStyle = BorderStyle.Fixed3D;
    //add the newly created TabPage
    //to the tabcontrol's collection of tab pages 
    browserTabControl.TabPages.Insert(
        browserTabControl.TabCount - 1, tpage);
    //create a WebBrowser object
    WebBrowser browser = new WebBrowser();
    browser.Navigate(homePage); 
    //add the browser object to the tab page 
    //you created previously
    tpage.Controls.Add(browser);
    browser.Dock = DockStyle.Fill;
    browserTabControl.SelectTab(tpage);
    //add some event handlers to your browser object
    browser.ProgressChanged += new 
      WebBrowserProgressChangedEventHandler(Form1_ProgressChanged);
    browser.DocumentCompleted += new 
      WebBrowserDocumentCompletedEventHandler(Form1_DocumentCompleted);
    browser.Navigating += 
      new WebBrowserNavigatingEventHandler(Form1_Navigating);
    browser.CanGoBackChanged += 
      new EventHandler(browser_CanGoBackChanged);
    browser.CanGoForwardChanged += 
      new EventHandler(browser_CanGoForwardChanged);
}

The example below shows how to get the current tab:

private WebBrowser getCurrentBrowser()
{
    return (WebBrowser)browserTabControl.SelectedTab.Controls[0];
}

How to get the favicon of a website

A favicon is a 16X16, 32X32, or 64X64 pixel square icon associated with a website. This icon is called favicon.ico, and can be found in in the root directory of a website. What you have to do in order to get the favicon of a particular website is to make a request to http://websitename/favicon.ico. You can get the icon from the response stream and use it in your application. For websites that don't have a favicon, I have used a default icon.

public static Image favicon(String u, string file)
{
    Uri url = new Uri(u);
    String iconurl = "http://" + url.Host + "/favicon.ico";

    WebRequest request = WebRequest.Create(iconurl);
    try
    {
        WebResponse response = request.GetResponse();

        Stream s = response.GetResponseStream();
        return Image.FromStream(s);
    }
    catch (Exception ex)
    {
        //return a default icon in case 
        //the web site doesn`t have a favicon
        return Image.FromFile(file);
    }
}

Links Bar

For the Links Bar, I used a ToolStrip control. A link button is represented by a ToolStripButton with the favicon image, and the website name as the text displayed on the button. The links are stored in an XML file that looks like this:

<favorits>
  <link url="http://www.google.ro/" >Google/<link>
  <link url="http://www.codeproject.com/">CodeProject</link>
  <link url="http://www.youtube.com/edu">Youtube/Edu</link>
</favorits>

The addNewLink() method shows how to add a new link. First, you open the XML file containing the links, then add a new XmlElement, setting the url attribute with the address of the website and the inner text of this element with the name you want this link to appear on the links bar. Then, you add a ToolStripButton to the links bar. The ToolStripButton control has a constructor that takes four arguments: public ToolStripButton(string text, Image image, EventHandler onClick, string name).

private void addLink(String url, string name)
{   
   //open the xml file 
    XmlDocument myXml = new XmlDocument();
   //and a new element to the xml file
    XmlElement el = myXml.CreateElement("link");
    el.SetAttribute("url", url);
    el.InnerText = name;

    if (!File.Exists(linksXml))
    {
        XmlElement root = myXml.CreateElement("links");
        myXml.AppendChild(root);
        root.AppendChild(el);
    }
    else
    {
        myXml.Load(linksXml);
        myXml.DocumentElement.AppendChild(el);
    }
    //if the links bar is visible then 
    //you have to add a ToolStripButton
    if (linkBar.Visible == true)
    {
       //create a new ToolStripButton object with the favicon image,
       //website name the click eventhandler to 
       //navigate to the specific web site               
        ToolStripButton b =
                  new ToolStripButton(el.InnerText, getFavicon(url), 
                  items_Click, el.GetAttribute("url"));
        b.ToolTipText = el.GetAttribute("url");
        //the MouseUp event is used 
        //for showing the context menu of this button 
        b.MouseUp += new MouseEventHandler(b_MouseUp);
        linkBar.Items.Add(b);
    }

    myXml.Save(linksXml);
}

The ToolStripButton control doesn't have a ContextMenu so if you want to add a context menu, you need to do some tricks. Here is my idea for solving this problem. In the designer view, I added a ContextMenu control named linkContextMenu and added some items on this context menu. When the user right-clicks a link, then this context menu is shown at the position where the mouse is. Then, you retain the website address and the name of this link (button that sent this event). For retaining the last address and name, I used two variables: adress and name. So, when the user clicks a context menu item, you can use these variables.

linkcontextmenu.png

string adress, name;

private void b_MouseUp(object sender, MouseEventArgs e)
{
    ToolStripButton b = (ToolStripButton)sender;
    adress = b.ToolTipText;
    name = b.Text;

    if (e.Button == MouseButtons.Right)
        linkContextMenu.Show(MousePosition);
}

Each context menu item has a click event handler. Below is an example of opening the link in a new window:

private void openInNewWindowToolStripMenuItem_Click(object sender, EventArgs e)
{
    WBrowser new_form = new WBrowser();
    new_form.Show();
    new_form.getCurrentBrowser().Navigate(adress);
}

History & Favorites

For storing History and Favorites, I used two XML files:

history.xml

<history>
  <item url="http://www.codeproject.com/" 
    lastVisited="19.02.2010 12:58:03" times="6" />
  <item url="http://www.google.ro/" 
    lastVisited="19.02.2010 12:52:09" times="2" />
  <item url="http://msdn.microsoft.com/" 
    lastVisited="13.08.2009 20:22:52" times="1" />
 </history>

favorites.xml

<favorites>
   <favorit url="http://images.google.ro/imghp?hl=ro&tab=wi">
       Google-images</favorit>
   <favorit url="http://www.yahoo.com/">Yahoo!</favorit>
</favorites>

For showing History and Favorites, I used a TreeView control. Here is an example of showing history based on the site name:

private void showHistory()
{
    historyTreeView.Nodes.Clear();
    //open the xml file
    XmlDocument myXml = new XmlDocument();

    if (File.Exists(historyXml))
    {
        myXml.Load(historyXml);
        DateTime now=DateTime.Now;
        
        //....
        
        if (comboBox1.Text.Equals("View By Site"))
        {
          historyTreeView.ShowRootLines = true;
          foreach(XmlElement el in myXml.DocumentElement.ChildNodes)
          {
              Uri site=new Uri(el.GetAttribute("url"));

              if(!historyTreeView.Nodes.ContainsKey(site.Host.ToString()))
                  historyTreeView.Nodes.Add(site.Host.ToString(), 
                                            site.Host.ToString(),0,0);
              //create a new tree node
              TreeNode node =new TreeNode(el.GetAttribute("url"), 3, 3);
              //set some properties of the new tree node you created    
              node.ToolTipText = el.GetAttribute("url") + 
                               "\nLast Visited: " + 
                               el.GetAttribute("lastVisited") + 
                               "\nTimes Visited: " + 
                               el.GetAttribute("times");
              node.Name = el.GetAttribute("url");
              //add a context menu to this node
              node.ContextMenuStrip = histContextMenu;
              //add this node to the treeview control    
              historyTreeView.Nodes[site.Host.ToString()].Nodes.Add(node);
         }
         //....
    }

For adding a website to Favorites, I created a form named AddFovorites which will be treated as a dialog. The constructor of this class takes a string argument representing the current web address. When the user clicks the "Add to favorites" button, the AddFavorites dialog will appear. The user can choose whether to add a favorite or a link.

addfavorit.PNG

private void toolStripButton8_Click(object sender, EventArgs e)
{
    if (getCurrentBrowser().Url != null)
    {        //show the AddFavorites dialog
        AddFavorites dlg = 
           new AddFavorites(getCurrentBrowser().Url.ToString());
        DialogResult res = dlg.ShowDialog();
            //if the user clicks OK   
        if (res == DialogResult.OK)
        {         
            if (dlg.favFile == "Favorites")
                //add a favorite to xml file and in treeview
                addFavorit(getCurrentBrowser().Url.ToString(), 
                           dlg.favName);
            //add a link in xml file and in links bar
            //the addLink() method is listed
            //in the Links Bar section of this article
            else addLink(getCurrentBrowser().Url.ToString(), 
                         dlg.favName);
        }
        dlg.Close();
    }
}

The addFavorit() method is listed below. It is similar to the addLink method, except it opens another XML file containing the favorite website, and it adds a TreeNode in favTreeView.

private void addFavorit(String url, string name)
{
    XmlDocument myXml = new XmlDocument();
    XmlElement el = myXml.CreateElement("favorit");
    el.SetAttribute("url", url);
    el.InnerText = name;
    if (!File.Exists(favXml))
    {
        XmlElement root = myXml.CreateElement("favorites");
        myXml.AppendChild(root);
        root.AppendChild(el);
    }
    else
    {
        myXml.Load(favXml);
        myXml.DocumentElement.AppendChild(el);
    }
    if (favoritesPanel.Visible == true)
    {
        TreeNode node = new TreeNode(el.InnerText, 
          faviconIndex(el.GetAttribute("url")), 
          faviconIndex(el.GetAttribute("url")));
        node.ToolTipText = el.GetAttribute("url");
        node.Name = el.GetAttribute("url");
        node.ContextMenuStrip = favContextMenu;
        favTreeView.Nodes.Add(node);
    }
    myXml.Save(favXml);
}

View Source

The WebBrowser control has a DocumentText property that represents the HTML contents of the page displayed in the control. For viewing the source of a website in Notepad, first create a temporary file, write the HTML content to this file, and then open the temporary file with Notepad.

private void sourceToolStripMenuItem_Click(object sender, EventArgs e)
{
    String source=("source.txt");
    StreamWriter writer =File.CreateText(source);
    writer.Write(getCurrentBrowser().DocumentText);
    writer.Close();
    Process.Start("notepad.exe", source);
}

Search

On the address bar, I have a text box where the user can enter the keywords he wants to search. This text box has a KeyDown event. When the user presses "Enter", the result will be shown in the current tab. The user can choose between Google Search or Live Search in the dropdown button near the search bar.

private void searchTextBox_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter)
        if (googleSearch.Checked == true)
            getCurrentBrowser().Navigate("http://" + 
              "google.com/search?q=" + searchTextBox.Text);
        else
            getCurrentBrowser().Navigate("http://search." + 
              "live.com/results.aspx?q="+searchTextBox.Text);                       
}

Saving Settings

Sometimes a user wants to save settings between application runs. For saving settings like home page, visibility of the menu bar or links bar, I used an XML file named "settings.xml".

<settings>
  <menuBar visible="True" />
  <adrBar visible="True" />
  <linkBar visible="True" />
  <favoritesPanel visible="True" />
  <SplashScreen checked="False" />
  <homepage>about:blank</homepage>
  <dropdown>15</dropdown>
</settings>

When the main form loads, these setting are read from the XML file. When the user changes a setting, the content of the XML file is changed. These changes are saved when the form is closed.

Changing the visibility of the Links Bar

In my main form, I have a context menu named toolBarContextMenu with the items in the image below. Each item has a Click event. When the user clicks one of the items in the context menu, then the visibility of that item is changed.

toolbarcontextmenu.PNG

private void linksBarToolStripMenuItem_Click(object sender, EventArgs e)
{
    linkBar.Visible = !linkBar.Visible;
    this.linksBarToolStripMenuItem.Checked = linkBar.Visible;
    
    //settings represents the xml file 
    //"settings.xml" opened when the form loads
    settings.DocumentElement.ChildNodes[2].Attributes[0].Value = 
                             linkBar.Visible.ToString();
}

Changing the home page

I created a form named InternetOptions which will be treated as a dialog. The user can change the homepage, appearance, or the number of dropdown items in the address bar.

options.PNG

String homePage;
 
InternetOption optionDialog = 
  new InternetOption(getCurrentBrowser().Url.ToString());
if (optionDialog.ShowDialog() == DialogResult.OK)
{
    //if the user setted a home page   
    if (!optionDialog.homepage.Text.Equals(""))
    {
        homePage = optionDialog.homepage.Text;
        //changing the setting in the xml file 
        //settings represents the xml file
        //"settings.xml" opened when the form loads
        settings.DocumentElement.ChildNodes[5].InnerText = 
                                 optionDialog.homepage.Text;
    }
}

Properties, Print, Print Preview, Page Setup, Save As

Some of the WebBrowser control methods are listed here:

  • public void ShowPropertiesDialog (): Opens the Internet Explorer Properties dialog box for the current document.
  • private void propertiesToolStripMenuItem_Click(object sender, EventArgs e)
    {
        getCurrentBrowser().ShowPropertiesDialog();
    }
  • public void ShowPageSetupDialog (): Opens the Internet Explorer Page Setup dialog box.
  • private void pageSetupToolStripMenuItem_Click(object sender, EventArgs e)
    {
        getCurrentBrowser().ShowPageSetupDialog();
    }
  • public void ShowPrintDialog (): Opens the Internet Explorer Print dialog box without setting the header and footer values.
  • private void printToolStripMenuItem_Click(object sender, EventArgs e)
    {
        getCurrentBrowser().ShowPrintDialog();
    }
  • public void ShowPrintPreviewDialog (): Opens the Internet Explorer Print Preview dialog box.
  • private void printPreviewToolStripMenuItem_Click(object sender, EventArgs e)
    {
        getCurrentBrowser().ShowPrintPreviewDialog();
    }
  • public void ShowSaveAsDialog (): Opens the Internet Explorer Save Web Page dialog box, or the Save dialog box of the hosted document if it is not an HTML page.
  • private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
    {
        getCurrentBrowser().ShowSaveAsDialog();
    }

Cut, Copy, Paste, Select All

The WebBrowser control has a Document property that gets an HtmlDocument representing the web page currently displayed in the control. On this HtmlDocument, you can execute specific commands like "Cut" or "Copy". The examples below show how you can do this.

//cut
private void cutToolStripMenuItem_Click(object sender, EventArgs e)
{
    getCurrentBrowser().Document.ExecCommand("Cut", false, null);

}
//copy
private void copyToolStripMenuItem_Click(object sender, EventArgs e)
{
    getCurrentBrowser().Document.ExecCommand("Copy", false, null);

}
//paste
private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
{
    getCurrentBrowser().Document.ExecCommand("Paste", false, null);
}
//select all
private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
{
    getCurrentBrowser().Document.ExecCommand("SelectAll", true, null);
}

What can be done further

There are two things that can be done further: one is to save the favicons of the favorites and links in XML files. This way, when the application loads, it doesn't have to make so many requests. Another thing that can be done is to use the App.config for saving settings.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here