Web Browser in C#






4.88/5 (143 votes)
A tabbed Web Browser in C# with favicons, History & Favorites, Links Bar, View Source, Search, and Print functionalities.
Contents
- Introduction
- Implementing Tab functionality
- How to get the favicon of a website
- Links Bar
- History & Favorites
- View Source
- Search
- Saving Settings
- Properties, Print, Print Preview, Page Setup, Save As
- Cut, Copy, Paste, Select All
- What can be done further
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.
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.
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.
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.
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.