Displaying Output As An HTML Page


The examples show how the .NET base classes make it very easy to download and process data from the Internet. However, so far you have only displayed files as plain text. Quite often you will want to view an HTML file in an Internet Explorer–style interface where the rendered HTML allows you to see what the Web document actually looks like. Unfortunately, there is not a .NET version of Microsoft's Internet Explorer, but that doesn't mean that you can't easily accomplish this task. Before the release of the .NET Framework 2.0, you could make reference to a COM object that was an encapsulation of Internet Explorer and use the .NET interop capabilities to have aspects of your application work as a browser. Now, using the .NET Framework 2.0, you can use the new built-in WebBrowser control available for your Windows Forms applications.

The WebBrowser control encapsulates the COM object even further for you making tasks that were once more complicated even easier. Besides using the WebBrowser control, another option is to use the pro- grammatic ability to call up Internet Explorer instances from your code.

When not using the new WebBrowser control, you can programmatically start an Internet Explorer process and navigate to a Web page using the Process class in the System.Diagnostics namespace:

 Process myProcess = new Process(); myProcess.StartInfo.FileName = "iexplore.exe"; myProcess.StartInfo.Arguments = "http://www.wrox.com"; myProcess.Start(); 

However, the preceding code launches Internet Explorer as a separate window. Your application has no connection to the new window and therefore cannot control the browser.

On the other hand, using new WebBrowser control allows you to display and control the browser as an integrated part of your application. The new WebBrowser control is quite sophisticated, featuring a large number of methods, properties, and events.

Allowing Simple Web Browsing from Your Applications

For the sake of simplicity, start by creating a Windows Form application that simply has a TextBox control and a WebBrowser control. You will build the application so that the end user will simply enter in a URL into the text box, press Enter, and the WebBrowser control will do all the work of fetching the Web page and displaying the resulting document.

In the Visual Studio 2005 designer, your application should look as shown in Figure 35-3.

image from book
Figure 35-3

With this application, when the end user types in a URL and presses the Enter key, this key will register with the application and the WebBrowser control will go off to retrieve the requested page, which will then be subsequently displayed in the control itself.

The code behind this application is illustrated here:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace CSharpInternet { partial class Form1 : Form { public Form1() { InitializeComponent(); } private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)13) { webBrowser1.Navigate(textBox1.Text); } } } } 

From this example, you can see that each key press the end user makes in the text box is captured by the textBox1_KeyPress event and if the character inputted is a carriage return (a press of the Enter key, which is (char)13), then you take action with the WebBrowser control. Using the WebBrowser control's Navigate method, you specify the URL (as a string) through the use of the textBox1.Text property. The end result is shown in Figure 35-4.

image from book
Figure 35-4

Launching Internet Explorer Instances

It might be that you are not interested in hosting a browser inside of your application as shown in the previous section but instead are only interested in allowing the user to find your Web site in a typical browser (for example, by clicking a link inside of your application). For an example of this task, create a Windows Form application that has a LinkLabel control on it. For instance, you can have a form that has a LinkLabel control on it that states "Visit our company website!"

Once you have this control in place, use the following code to launch your company's Web site in an independent browser as opposed to directly being in the form of your application:

 private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { WebBrowser wb = new WebBrowser(); wb.Navigate("http://www.wrox.com", true); } 

In this example, when the LinkLabel control is clicked by the user, a new instance of the WebBrowser class is created. Then, using the WebBrowser class's Navigate method, the code specifies the location of the Web page as well as a boolean value that specifies whether this end-point should be opened within the Windows Form application (a false value) or from within an independent browser (using a true value). By default, this is set to false. With the preceding construct, when the end user clicks the link found in the Windows application, a browser instance will be instantiated and the Wrox Web site will be immediately launched.

Giving Your Application More IE Type Features

You will notice that when working with the previous example, in which you used the WebBrowser control directly in the Windows Form application, when you clicked on the links the text within the TextBox control was not updated to show the URL of where exactly you were in the browsing process. You can fix this by listening for events coming from the WebBrowser control and adding handlers to the control.

Updating the form's title with the HTML page's title is an easy thing to accomplish. You just have to create DocumentTitleChanged event and update the Text property of the form:

 private void webBrowser1_DocumentTitleChanged(object sender, EventArgs e) { this.Text = webBrowser1.DocumentTitle.ToString(); } 

In this case, when the WebBrowser control notices that the page title has changed (due to changing the page viewed), the DocumentTitleChanged event will fire. In this case, you change the form's text box based on the complete URL of the page being viewed. To do this, you can use the WebBrowser control's Navigated event:

 private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e) { textBox1.Text = webBrowser1.Url.ToString(); } 

In this case, when the requested page is finished being downloaded in the WebBrowser control, the Navigated event is fired. In your case, you simply update the Text value of the textBox1 control to be the URL of the page. This means that once a page is loaded in the WebBrowser control's HTML container and if the URL changes in this process (for instance, if there is a redirect), then the new URL will be shown in the text box. If you employ these steps and navigate to the Wrox Web site (http://www.wrox.com), you will notice that the page's URL will immediately change to http://www.wrox.com/WileyCDA/. This process also means that if the end user clicks one of the links contained within the HTML view, the URL of the newly requested page will also be shown in the text box as well.

Now if you run the application with the preceding changes put into place, you'll find that the form title and address bar work as they do in Microsoft's Internet Explorer, as demonstrated in Figure 35-5.

image from book
Figure 35-5

The next step is to create an IE-like toolbar that will allow the end user to control the WebBrowser control a little more. This means that you will incorporate buttons such as Back, Forward, Stop, Refresh, and Home.

Rather than using the ToolBar control, you'll just add a set of Button controls at the top of the form where you currently have the address bar. Add five buttons to the top of the control as illustrated in Figure 35-6.

image from book
Figure 35-6

In this example, the text on the button face is changed to indicate the function of the button. Of course, you can even go as far as to use a screen capture utility to "borrow" button images from IE and use those. The buttons should be named buttonBack, buttonForward, buttonStop, buttonRefresh, and buttonHome. To get the resizing to work properly, make sure you set the Anchor property of the three buttons on the right to Top, Right.

On startup, buttonBack, buttonForward, and buttonStop should be disabled because there is no point to the buttons if there is no initial page loaded in the WebBrowser control. You will later tell the application when to enable and disable the Back and Forward buttons yourself, depending on where the user is in the page stack. Also, when a page is being loaded, you will need to enable the Stop button — but also, you will need to disable the Stop button once the page has finished being loaded.

First off though, you'll add the functionality behind the buttons. The WebBrowser class itself has all of the methods that you need, so this is all very straightforward:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; namespace CSharpInternet {     partial class Form1 : Form     {         public Form1()         {             InitializeComponent();         }         private void webBrowser1_DocumentTitleChanged(object sender, EventArgs e)         {     this.Text = webBrowser1.DocumentTitle.ToString(); } private void textBox1_KeyPress(object sender, KeyPressEventArgs e) {     if (e.KeyChar == (char)13)     {         webBrowser1.Navigate(textBox1.Text);     } } private void webBrowser1_Navigated(object sender,     WebBrowserNavigatedEventArgs e) {     textBox1.Text = webBrowser1.Url.ToString(); } private void Form1_Load(object sender, EventArgs e) { buttonBack.Enabled = false; buttonForward.Enabled = false; buttonStop.Enabled = false; } private void buttonBack_Click(object sender, EventArgs e) { webBrowser1.GoBack(); textBox1.Text = webBrowser1.Url.ToString(); } private void buttonForward_Click(object sender, EventArgs e) { webBrowser1.GoForward(); textBox1.Text = webBrowser1.Url.ToString(); } private void buttonStop_Click(object sender, EventArgs e) { webBrowser1.Stop(); } private void buttonHome_Click(object sender, EventArgs e) { webBrowser1.GoHome(); textBox1.Text = webBrowser1.Url.ToString(); } private void buttonRefresh_Click(object sender, EventArgs e) { webBrowser1.Refresh(); } private void buttonSubmit_Click(object sender, EventArgs e) { webBrowser1.Navigate(textBox1.Text); } private void webBrowser1_CanGoBackChanged(object sender, EventArgs e) { if (webBrowser1.CanGoBack == true) { buttonBack.Enabled = true; } else { buttonBack.Enabled = false; } } private void webBrowser1_CanGoForwardChanged(object sender, EventArgs e) { if (webBrowser1.CanGoForward == true) { buttonForward.Enabled = true; } else { buttonForward.Enabled = false; } } private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e) { buttonStop.Enabled = true; } private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { buttonStop.Enabled = false; } } } 

A lot of different activities are going on in this example because there are so many options for the end user when using this application. First off, for each of the button-click events, there is a specific WebBrowser class method assigned as the action to initiate. For instance, for the Back button on the form, you simply use the WebBrowser control's GoBack() method. And for the other buttons, it is the same — for the Forward button you have the GoForward() method and for the other buttons, you have methods such as Stop(), Refresh(), and GoHome(). This makes it fairly simple and straightforward to create a toolbar that will give you similar action as that of Microsoft's Internet Explorer.

When the form is first loaded, the Form1_Load event disables the appropriate buttons. From there, the end user can enter in a URL into the text box and click the Submit button to have the application retrieve the desired page.

To manage the enabling and disabling of the buttons, you have to key into a couple of events. As mentioned before, whenever downloading begins you need to enable the Stop button. For this, you simply added an event handler for the Navigating event to enable the Stop button:

private void webBrowser1_Navigating(object sender,     WebBrowserNavigatingEventArgs e) {     buttonStop.Enabled = true; }

Then the Stop button is again disabled when the document is finished being loaded:

private void webBrowser1_DocumentCompleted(object sender,     WebBrowserDocumentCompletedEventArgs e) {     buttonStop.Enabled = false; }

To enable and disable the appropriate Back and Forward buttons, it really depends on the ability to go backward or forward in the page stack. This is achieved using both the CanGoForwardChanged() and the CanGoBackChanged() events:

private void webBrowser1_CanGoBackChanged(object sender, EventArgs e) {     if (webBrowser1.CanGoBack == true)     {         buttonBack.Enabled = true;     }     else     {         buttonBack.Enabled = false;     } } private void webBrowser1_CanGoForwardChanged(object sender, EventArgs e) {     if (webBrowser1.CanGoForward == true)     {         buttonForward.Enabled = true;     }     else     {         buttonForward.Enabled = false;     } }

Run the project now and visit a Web page and click through a few links. You should also be able to use the toolbar to enhance your browsing experience. The end product is shown in Figure 35-7.

image from book
Figure 35-7

Showing Documents Using the WebBrowser Control

You are not just limited to Web pages for use within the WebBrowser control. In fact, you can allow the end user to view many different types of documents. So far, you have seen how to use the WebBrowser control to access documents that have been purely accessible by defining a URL. However, the WebBrowser control also allows you to use an absolute path and define end points to files such as Word documents, Excel documents, PDFs, and more.

For instance, suppose that you are using the following code snippet:

 webBrowser1.Navigate("C:\\Financial Report.doc"); 

This would open the Word document in your application. Not only would the document appear in the WebBrowser control, but the Word toolbar would also be present. This is illustrated in Figure 35-8.

image from book
Figure 35-8

In Figure 35-9 is the WebBrowser control showing an Adobe PDF file.

image from book
Figure 35-9

In addition to simply opening up specific documents in the control, users have the ability to drag-and- drop documents onto the WebBrowser control's surface and the document dropped will automatically be opened within the control. To turn off this ability (which is enabled by default), you will have to set the WebBrowser control's AllowWebBrowserDrop property to false.

Printing Using the WebBrowser Control

Not only can users use the WebBrowser control to view pages and documents; they can also use the control to send these pages and documents to the printer for printing. To print the page or document being viewed in the control, simply use the following construct:

 webBrowser1.Print(); 

Like before, you don't have to view the page or document in order to print it. For instance, you can use the WebBrowser class to load an HTML document and print it without even displaying the loaded document. This would be accomplished as shown here:

 WebBrowser wb = new WebBrowser();  wb.Navigate("http://www.wrox.com");  wb.Print(); 

Displaying the Code of a Requested Page

In the beginning of this chapter, you used the WebRequest and the Stream classes to get at a remote page to display the code of the requested page. You used this code to accomplish this task:

public Form1() {    InitializeComponent();    System.Net.WebClient Client = new WebClient();    Stream strm = Client.OpenRead("http://www.reuters.com");    StreamReader sr = new StreamReader(strm);    string line;    while ( (line=sr.ReadLine()) != null )    {       listBox1.Items.Add(line);    }     strm.Close(); }

Now, however, with the introduction of the WebBrowser control, it is quite easy to accomplish the same results. To accomplish this, change the browser application that you have been working on thus far in this chapter. For this change, simply add a single line to the Document_Completed event as illustrated here:

 private void webBrowser1_DocumentCompleted(object sender,  WebBrowserDocumentCompletedEventArgs e) { buttonStop.Enabled = false; textBox2.Text = webBrowser1.DocumentText.ToString(); } 

In the application itself, add another TextBox control below the WebBrowser control. The idea is that when the end user requests a page not only will you display the visual aspect of the page, but the code for the page as well in the TextBox control. The code of the page is displayed simply using the DocumentText property of the WebBrowser control, which will give you the entire page's content as a String. The other option is to get the contents of the page as a Stream using the DocumentStream property. The end result of the adding the second TextBox to display the contents of the page as a String is shown in Figure 35-10.

image from book
Figure 35-10

The WebRequest and WebResponse Hierarchy

In this section you take a closer look at the underlying architecture of the WebRequest and WebResponse classes.

Figure 35-11 illustrates the inheritance hierarchy of the classes involved.

image from book
Figure 35-11

The hierarchy contains more than just the two classes you have used in your code. You should also know that the WebRequest and WebResponse classes are both abstract and cannot be instantiated. These base classes provide general functionality for dealing with Web requests and responses independent of the protocol used for a given operation. Requests are made using a particular protocol (HTTP, FTP, SMTP, and so on) and a derived class written for the given protocol will handle the request. Microsoft refers to this scheme as pluggable protocols. Remember in the code you examined earlier, your variables are defined as references to the base classes; however, WebRequest.Create() actually gives you an HttpWebRequest object, and the GetResponse() method actually returns an HttpWebResponse object. This factory-based mechanism hides many of the details from the client code, allowing support for a wide variety of protocols from the same code base.

The fact that you need an object specifically capable of dealing with the HTTP protocol is clear from the URI that you supply to WebRequest.Create(). WebRequest.Create() examines the protocol specifier in the URI to instantiate and return an object of the appropriate class. This keeps your code free from having to know anything about the derived classes or specific protocol used. When you need to access specific features of a protocol, you might need the properties and methods of the derived class, in which case you can cast your WebRequest or WebResponse reference to the derived class.

With this architecture you should be able to send requests using any of the common protocols. However, Microsoft currently only provides derived classes to cover the HTTP, HTTPS, FTP, and FILE protocols. The FTP option is the latest option provided by the .NET Framework 2.0. If you want to utilize other protocols, for example, SMTP, you will need to fall back on the Windows API, write your own classes, or wait for an independent software vendor to write some of the suitable .NET classes.




Professional C# 2005
Pro Visual C++ 2005 for C# Developers
ISBN: 1590596080
EAN: 2147483647
Year: 2005
Pages: 351
Authors: Dean C. Wills

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net