Entering test data can be a tedious chore. Recently I found a web site that makes it easier to populate your database tables with realistic data, http://www.generatedata.com/ This is a very useful online utility. It really saves me a lot of time because I often waste an incredible amount of time just deciding on a name for a fictitious user. I also waste time looking for real addresses, phone numbers, etc. 

I wish I had thought of this as a project because it would have been easy to create and it gives you a certain amount of fame with other programmers. There are a few improvements that could be made to it so maybe somebody in the ASP.NET community could create an alternative service with the following improvements:

  1. Generate random amounts in various currencies. Don't know why the original version overlooks this obvious need.
  2. Add SQL Server and Access to the database choices.
  3. Generate random floats
  4. Generate random boolean values
  5. Fixed string values. You can sort of do this by entering a custom list with just one value.

Recently I've been studying RPG II for the Infinite 36, an old IBM programming language that was designed for 80 column punchcards. RPG II is probably the most horrible programming language that man has ever devised. Sometimes your code is a single character which has to be in an exact column. There is also a fixed logic that you have to work around. But it is the matter of getting a character in the right column that gives me a pain. The Infinite 36 is an old emulator of the IBM System 36 for the PC. It has some green screen RPG editors but I prefer to use UltraEdit.

I have used ASP.NET to write an utility to help me troubleshoot my RPG II code. The utility web page displays the code in a HTML table with 80 columns. I added some cryptic ruler lines to help me figure out what some of the columns are used for. These ruler lines are based on a few old RPG code editing tools that used these ruler lines. I have a MS-DOS program for editing RPG code which uses such ruler lines.

I added a semi-transparent floating row of numbered columns to overlay the table. As I scroll down the page the numbered top row is no longer visible so I used the jQuery floating div plugin to make it float. In addition, I gave all the table cells a title with their cell number so I can mouse over a table cell to see its position.Click on the thumbnail image below to see a larger image.

RPG Code Viewer 

In addition to the the column numbers and cryptic rulers, I added some syntax highlighting. All of the single character codes make syntax highlighting impractical but file names, fields, edit words, and calculation operators and factors can be color coded. Here is the link to the download for my RPG Code Viewer.

The only thing I like about RPG II programming is that it is very obscure. Some day I may charge $200.00 an hour for RPG II work to compensate for the aggravation. There is plenty of opportunity to create tools for RPG II programming because there is very little available. I did find an Excel spreadsheet designed as a printing spacing chart. I also bought a RPG II ruler which is a metal ruler that you can use to check the columns in a RPG source code printout.

I'm currently studying FoxPro 2.6. For MS-DOS. Yes, the company I am working for is still using applications written for FoxPro 2.6! I have to run this old MS-DOS database system in Virtual PC. So the last programming book I've read was Charles Siegel's Mastering FoxPro 2 written in 1991. The applications are completely undocumented (grrrr!) so my first step was to create a data dictionary (aka database schema). In FoxPro this can be done through the command DISPLAY STRUCTURE.

However, it is possible to connect to these old MS-DOS FoxPro database files using ASP.NET. First you will need the Microsoft OLE DB Provider for Visual FoxPro 9.0. It is important to realize that every table in a FoxPro database exists within its own DBX file with maybe a CDX file for the index. So to access a particular table you actually need to access a particular file location. I had to create folders for each table database and then set the data source as a folder:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.OleDb;
using System.Data.Odbc;

public partial class FoxPro_Query : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            OleDbConnection cn = new OleDbConnection("Provider=VFPOLEDB.1;Data Source=C:\\Projects\\FoxPro\\WZ\\CLIENT;Collating Sequence=general;");
            OleDbDataAdapter da = new OleDbDataAdapter("SELECT subid, fund_src, lname, fname, addr1, addr2, city, state, zip, phone_h, county, homeowner, notes, directions FROM CLIENT WHERE Lname = 'ROBBINS'", cn);
            DataTable objDataTable = new DataTable();
            da.Fill(objDataTable);

            GridView1.DataSource = objDataTable;
            GridView1.DataBind();

            cn.Close();
        }
        catch (OleDbException ode)
        {
            lblErrorMessage.Text = ode.ToString();
        }
    }
}

It is also possible to get the schema of the FoxPro database table and bind it to a GridView for a web page version of the database structure. 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.OleDb;
using System.Data.Odbc;

public partial class FoxPro : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            OleDbConnection cn = new OleDbConnection("Provider=VFPOLEDB.1;Data Source=C:\\Projects\\FoxPro\\WZHSTDET;Collating Sequence=general;");
            cn.Open();
            DataTable objDataTable = new DataTable();
            objDataTable = cn.GetSchema("Columns");

            GridView1.DataSource = objDataTable;
            GridView1.DataBind();

            cn.Close();
        }
        catch (OleDbException ode)
        {
            lblErrorMessage.Text = ode.ToString();
        }
    }

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            e.Row.Cells[2].Text = Enum.GetName(typeof(OleDbType), Convert.ToInt32(e.Row.Cells[2].Text));
        }
        
    }
}

Hopefully this is just the first step in getting these applications off of MS-DOS FoxPro 2.6 and onto a more contemporary development framework. The current system seems to give its users a lot of headaches.

I've been working on my job skills to remain employable. A lot of people are losing their jobs and then getting depressed because they have nothing to do except look for a job. They should be spending their time more constructively. I don't have much to do at work so yesterday I worked through a tutorial on Firefox Extension Development. I use Firefox all day at work and home because its extensions are useful for web development. It will be cool to create my own custom extensions. Today I experimented with the localization aspect of a Firefox extension. There are several things that were left out of the tutorial.

  1. You need to install language packs to change the language that Firefox uses in its application interface. HTML clipboard http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/xpi/
  2. You need to HTML clipboardassign a user-interface language to a profile. There is a Locale-Switcher extension to make it easier.
  3. Your Language Document Template Definition (DTD) files cannot contain accent marks. You have to use HTML entities like é to ensure valid XML.
  4. All of your XUL files need to reference the DTD.
  5. You need to add a line in your chrome.manifest file for the locales.
I'm currently studying German because I plan to visit Berlin next year for my vacation. Changing Firefox to German will help me to learn the language. I've become very interested in learning how various programs and application frameworks handle localization to support multiple languages.

Pennsylvania has not passed a budget for over two months. I was laid off from my full time job because of that. Now that I am collecting unemployment, I’ve had enough spare time to learn French. I have read five books on the French language. I think learning French is more worthwhile than learning Silverlight!

I can read enough French to explore French web sites. The French version of Wikipedia is especially useful in expanding my vocabulary. I also watch a home shopping channel via streaming video because the French spoken on that channel is very clear.

If Pennsylvania does not pass a budget soon I will have time to learn German too!


Pennsylvanie n'a pas passé un budget (ses dépenses en fonction de) depuis plus de deux mois. J'ai été licencié de mon emploi à temps plein à cause de cela. Maintenant que je suis la collecte de chômage, j'ai eu assez de temps libre pour apprendre le français. J'ai lu cinq livres sur la langue française. Je pense que l'apprentissage du français est plus intéressant que d'apprendre Silverlight!

Je peux lire assez de français pour explorer les sites Internet français. La version française de Wikipédia est particulièrement utile pour élargir mon vocabulaire. Je regarde aussi un chaîne de téléachat via le streaming vidéo, car le français parlé sur ce chaîne est très claire.

Si la Pennsylvanie ne passe pas d'un budget bientôt puis j'aurai le temps d'apprendre l'allemand aussi!

I’ve been having a problem with Windows Live Writer after I installed a WordPress plugin, Now Reading. That plugin allows me to show the books I’m currently reading on the sidebar.

Windows Live Writer-Error

If I have that plugin enabled, I would get the error above, “Invalid Server Response – The response to the blogger.getUsersBlogs method received from the blog server was invalid: Invalid response document returned from XmlRpc server”. Many people have encountered that error and I was able to find several solutions but none of them fixed my problem. Being a rock star programmer, I decided that I would lick this problem and continue to use my plugin with Windows Live Writer. I believe in bending computers to my will instead of living with their problems.

In plain English the error message means the XML response from WordPress does not validate because it is not valid XML. I don’t know why they could not say that in the error message. You can tell it was written by a Microsoft employee!

In order to troubleshoot this problem you need to see the XML response. I did find a XML-RPC debugger at:  http://gggeek.raprap.it/debugger/ but it is not very helpful when the XML is malformed. It can give you some insight into the methods that are available though. In order to figure out exactly what was going on, I wrote a simple VBScript to submit a POST request to the xmlrpc.php file and saved the response to a file. That’s right, I used VBScript! VBScript is perfect for simple tasks that do not warrant a lot of effort.

   1: ' #################################################
   2: ' # VBScript To Call WordPress XMLRPC             #
   3: ' # Need to examine XML response to troubleshoot  #
   4: ' # programmed by Robert S. Robbins on 06/10/2009 #
   5: ' #################################################
   6:  
   7: Set oXMLHTTP = WScript.CreateObject("MSXML2.XMLHTTP")
   8: oXMLHTTP.open "POST", "http://www.williamsportwebdeveloper.com/cgi/wp/xmlrpc.php",False
   9:  
  10: oXMLHTTP.setRequestHeader "Content-Type", "text/xml"
  11: 'oXMLHTTP.send "<?xml version='1.0'?><methodCall><methodName>system.listMethods</methodName><params></params></methodCall>"
  12: oXMLHTTP.send "<?xml version='1.0'?><methodCall><methodName>demo.sayHello</methodName><params></params></methodCall>"
  13:  
  14: 'MsgBox oXMLHTTP.responseText,vbInformation, "XMLRPC Response"
  15:  
  16: Set fso = WScript.CreateObject("Scripting.FileSystemObject")
  17: strWorkingDirectory = Left(WScript.ScriptFullName, InStrRev(WScript.ScriptFullName,"\")-1)
  18: ' unicode format designator -1 solves the "Invalid procedure call or argument" error
  19: Set objOutputFile = fso.CreateTextFile(strWorkingDirectory & "\wp-response.xml", True, -1)
  20: objOutputFile.Write oXMLHTTP.responseText
  21: Set objOutputFile =  Nothing
  22:  
  23: MsgBox  "Done Processing!"

This script calls a XmlRpc method, it does not matter which one, and saves the result to a file. I was able to determine that the XML was invalid because 2 characters where truncated from the end of the last tag.

I’m not exactly sure why two characters get truncated with that plugin enabled but I did find the closing tag in the class-IXR.php file in the wp-includes directory. This file uses a XML template contained within within a nowdoc string, a PHP string that is not parsed. Apparently this is a PHP version of the <![CDATA[ ]]> construct but is meant to exclude quotes from parsing. Anyway, I was able to solve my problem by adding two more line breaks before the closing EOD;. This may not be the only problem with your XML. I also had a problem with a BOM (Byte Order Mark) that Microsoft Expression Web sneakily added to a PHP file I edited (Thanks, Expression Web, that was real sly of you). But I recently upgraded WordPress and I only had to apply my hack to the class-IXR.php file to get Windows Live Writer to accept the XML response from my WordPress blog.

My vacation in Paris, France was a great success and fulfilled one of my dreams. You can read about my travels on my personal blog at: http://williamsportwebdeveloper.com/cgi/wp/

I’ve decided to learn French as a second language even though I did not need to know any French in Paris. Learning a foreign language requires a huge commitment of time and effort, far more than is necessary to learn a programming language. You need a really good reason to learn a second language. As a programmer I am all too familiar with the temptation to learn many computer languages which you’ll never actually use. It can be a waste of time to learn a programming language. I’ve already decided that life is too short to learn Java.

It is actually quite hard to think of a good reason to learn French. Most of the reasons given for studying French as a second language don’t make any sense, especially if you don’t plan to move to France. For example, it does not matter how influential France is as a nation. You don’t need to know French to follow the international news relating to French foreign policy. You also don’t need to know French to vacation in France. That may infuriate the French, but it doesn’t make sense to spend years learning a language just so you can use it for one week when you’ll really need it, occasionally.

The main reason I’ve decided to learn French is to explore the uncharted territory of their geek culture. It may surprise you to learn that there is such a thing as the French geek. The stereotype of the French as artists and intellectuals conceals a far more extensive culture. The French also love comic books, science fiction, horror, video games, and pop music. Their comic book industry, known as bandes dessinées or BD for short, rivals the Japanese manga but is virtually unknown here in the United States. I was in a Borders bookstore last week and saw an entire aisle devoted to Japanese manga in paperback books called tankōbon. There was a smaller bookshelf for Marvel, DC, and other American graphic novels. However I did not find a single bandes dessinées at Borders.

In addition to an unexplored world of graphic novels, the French also publish many science fiction novels which are never translated into English. Some of this science fiction uses historical references to the reign of Louis XIII and the periods of French Baroque and Classicism in a way that is really bizarre and amusing. There are also spy novels and other forms of pulp fiction that will never be shared with the Anglosphere (i.e. the totality of (English-speaking) nations).

I think it would be fun to explore this world of trashy French culture because it goes against the stereotype of the French as sophisticated snobs. I’ve become pretty bored with American culture and its predictable output.

So what does this have to do with programming? Well, programmers are often geeks so I’m staying within my culture with this new obsession. I also intend to visit many more French web sites and I’ll keep an eye out for any innovative uses of technology that have not made it to the English Internet. 

I’m going to Paris France for my vacation this year! I’m very excited about it because I’ve always been a bit of a Francophile. Unfortunately, I don’t speak French so, being a IT professional, I’ve sought a technological solution for the language barrier. I’m not sure that I’ll need to speak any French because I’m going on a guided tour which should reduce my interaction with the locals.

I’ve already blogged about ASP.NET’s support for internationalization and browser languages on my WordPress blog at: ASP.NET 2.0 Culture – Web Site Internationalization. I also blogged about Elgg’s support for languages at Elgg Languages. I’ve done some additional research since then into how PHP supports internationalization and I looked at how all the browsers implement language settings.

Firefox and Opera are the best browsers to use if you are working on making a web site international because they are the only browsers that allow you to indicate the browser language in the user agent string. In Firefox:

  1. To change the browser language type about:config in the address bar and press Enter.
  2. Enter general.useragent.locale in the Filter textbox.
  3. Change en-US to fr-FR or change it back to en-US.

However, I don’t know of a single web site that attempts to detect the browser language by checking the user agent string which will almost always indicate en-US even when your browser language is not set to that. Even with my browser language set to fr-FR, only Google, Microsoft, and Facebook accommodated me with French text. There seems to be some debate over whether it is a good idea to detect browser language settings. Some developers argue that providing content in the appropriate language based on the browser language is the proper way to handle internationalization while others argue that you need to give visitors a means to explicitly change the language using flags because it has become the expected method. In my opinion, you should use both methods because a bilingual visitor will not want to be stuck with the version of the site that matches his browser language settings.

Internet Explorer 8 seems to totally ignore the browser language settings. Even Google appears in English when I set my browser language to fr-FR in Internet Explorer 8. Only Google ignores the browser language settings for Internet Explorer 8. The Safari browser provides no means to change the browser language although you can change the application interface into French by copying the fr.lproj folder over the en.lproj folder. Opera does allow you to change the preferred language for web pages and you can change the user interface language to French by downloading the ouw960_fr.lng file which causes the user agent string to change to: Opera/9.63 (Windows NT 5.1; U; fr) Presto/2.1.1.

The browser language setting is communicated to the web server using the Accept-Language header in each request. In ASP.NET 2.0 you really don’t need to deal with this because the framework has built-in support for localization using the page directives UICulture and Culture. However, if you want to redirect to a page based on the browser language then you can use the following code in your Global.asax file:

   1: Sub Application_Start(ByVal sender As [Object], ByVal e As EventArgs)
   2:         Dim LanguageArray As String() = System.Web.HttpContext.Current.Request.UserLanguages
   3:         If LanguageArray(0).Contains("fr") Then
   4:             System.Web.HttpContext.Current.Response.Redirect("bonjour.htm")
   5:         End If
   6: End Sub

In PHP you can get the Accept-Language header using the server variable $_SERVER['HTTP_ACCEPT_LANGUAGE'];  and then set the locale using  setlocale(LC_ALL, 'fr-FR@euro', 'fr-FR', 'fr-fr');  which will automatically format the date using French for the month names and weekday names. You then need to set the Time Zone using putenv("TZ=Europe/Paris"); to get a 24 hour time in the Central European Time zone. On a Windows server the money_format function will not be available to you so you’ll need to define your own function for that.

But I’ve found a more interesting technological solution for the language barrier. I bought a Pocket PC translator from ECTACO. This device looks like a Pocket PC and it is Microsoft Windows Powered but it is really a highly specialized device with a built-in microphone and large speaker. I’m not sure what operating system it is running but it does not look like Windows Mobile 2003. I think its audio phrasebook may come in handy although it could make an awkward social situation even more awkward. The original SD card did not leave enough room for any additional audio files but I managed to copy everything over to a 2 GB SD card so I could put more MP3s on it.


Find more videos like this on VloggerHeads

I recently finished reading the book ASP.NET 3.5 Social Networking by Andrew Siemer. I was very interested in this book because I want to build a social networking site designed for vloggers and ASP.NET is my area of expertise. Currently I'm working to customize the Elgg social networking web application using PHP because it is open source and has an active developer community.

Unfortunately, developing a social networking application is a big project, not something the lone developer can accomplish. It really requires an integrated suite of web applications with modules for blogging, forums, groups, media galleries, etc. Andrew Siemer has done an impressive job of creating the framework of a social networking web application as documented in his book but it is by no means feature complete. There was no mention in the book of any plans to make this an open source project.

The author has clearly been keeping up with changes in technology and methodology. As far as ASP.NET 3.5 goes, he made extensive use of LINQ to SQL but was unable to use MVC which wasn't available at the time, although he managed to implement a MVP (Model View Presenter) design pattern. He also made use of open source tools like Lucene.NET, MemCached, StructureMap, and NUnit. I don't have any experience with those tools and I'm not up to speed with ASP.NET 3.5 but I considered this a bonus because I learned something new.

Even though I'm not using ASP.NET on my social networking project I still wanted to read this book to pick up on some tips on how to design such an application. Andrew Siemer provides plenty of explanation for his design decisions including how his database schema is structured according to the project requirements. This can eliminate one of the biggest stumbling blocks to a large project because a lot of time is wasted just figuring out how to design the database. Elgg is using the Entity Attribute Value model for its database and there is some debate over how well this will scale.

Although Andrew Siemer added considerable complexity to his project by using StructureMap, I guess this is wise because a social networking web application needs to be flexible. This design decision would definitely make sense for an open source project. StructureMap is a Dependency Injection tool written in C# for .NET development. StructureMap is also a generic "Plugin" mechanism for flexible and extensible .NET applications. In other words, it allows other developers to replace an object with some other implementation.

Social networking sites tend to get a lot of feature requests and suggestions from their large community of users. You really have to participate on several sites to get a sense of what the users are likely to need. Although the author anticipated many potential issues and requirements he did neglect to include some standard features. For example, he does not provide a means for members to customize their profile though CSS. Elgg also does not allow users to design their profile page and I know vloggers would miss this as they currently have a lot of fun creating new banners on Vloggerheads. I believe that vlogging is essential to create a really strong sense of online community so I found the media gallery component of the design particularly lacking. But you would need an entire video sharing module to really address that need. That is a huge project in its own right. I've learned that comment threading is really important for social networking sites. Without it you get users typing the @ sign in their comments to indicate who they are replying to and that is just an awkward user hack to work around a serious design flaw in the application.

Although this is a thick book, 556  pages, most of the content is code listings so you won't need to invest too much time in reading it. You may feel a little lost if you haven’t been following the rapid changes in the ASP.NET framework and the additional open source tools require additional work to familiarize yourself with them because they are not part of the ASP.NET framework.

Yesterday I attempted to create an ASP.NET page which used every single page event in order to better understand how to use each event. You cannot find any sample code for many page events. I managed to write code for every event except Page_AbortTransaction, Page_CommitTransaction, Page_DataBinding, and Page_Disposed which aren't being fired for this page. I tried to use meaningful examples but some of the code may be pointless. Let me know if you see any mistakes or have suggestions for improvements because this has gone into my notes.

The ASPX page includes a placeholder for adding a dynamic control and a GridView for experimenting with control rendering. I used the Northwind database for sample data. I also used a master page.

   1: <%@ Page Language="VB" MasterPageFile="~/Default.master" AutoEventWireup="false" CodeFile="LifeCycle.aspx.vb" Inherits="LifeCycle" title="ASP.NET 2.0 Life Cycle" %>
   2: <%@ MasterType VirtualPath="~/Default.master" %>
   3: <asp:Content ID="Content1" ContentPlaceHolderID="Main" Runat="Server">
   4:     <asp:PlaceHolder runat="server" id="LabelPlaceHolder" />
   5:     <br />
   6:     <asp:GridView ID="GridView1" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None">
   7:         <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
   8:         <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
   9:         <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
  10:         <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
  11:         <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
  12:         <EditRowStyle BackColor="#999999" />
  13:         <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
  14:     </asp:GridView>
  15: </asp:Content>

The VB code behind file uses a text file trace listener to log the page events as they are fired. That actually has to be set up in the web.config file. The Page_PreRenderComplete has some code commented out. This code adds the HTML rendered by the entire page to the log file but it causes an error about an extra form tag so I only left it in for debugging purposes. The only interesting things I'm doing is adjusting the column header text for the GridView and adding a top row. Some of the other page event code could use better examples.

   1: Imports System.Diagnostics
   2: Imports System.Data
   3: Imports System.Data.SqlClient
   4: Imports System.IO
   5:  
   6: Partial Class LifeCycle
   7:     Inherits System.Web.UI.Page
   8:  
   9:     Protected Sub Page_AbortTransaction(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.AbortTransaction
  10:         System.Diagnostics.Trace.WriteLine("Page_AbortTransaction " & Now())
  11:     End Sub
  12:  
  13:     Protected Sub Page_CommitTransaction(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.CommitTransaction
  14:         System.Diagnostics.Trace.WriteLine("Page_CommitTransaction " & Now())
  15:     End Sub
  16:  
  17:     Protected Sub Page_DataBinding(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.DataBinding
  18:         System.Diagnostics.Trace.WriteLine("Page_DataBinding " & Now())
  19:     End Sub
  20:  
  21:     Protected Sub Page_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
  22:         System.Diagnostics.Trace.WriteLine("Page_Disposed " & Now())
  23:     End Sub
  24:  
  25:     Protected Sub Page_Error(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Error
  26:         ' Use this event to log a page error
  27:         Dim objException As Exception = Server.GetLastError().GetBaseException()
  28:         System.Diagnostics.Trace.WriteLine(objException.ToString())
  29:         System.Diagnostics.Trace.WriteLine("Page_Error " & Now())
  30:     End Sub
  31:  
  32:     Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
  33:         ' Use this event to read or initialize control properties.
  34:         Dim ContentPlaceHolder1 As ContentPlaceHolder = CType(Master.FindControl("Main"), ContentPlaceHolder)
  35:         Dim LabelPlaceHolder As PlaceHolder = CType(ContentPlaceHolder1.FindControl("LabelPlaceHolder"), PlaceHolder)
  36:         Dim lblMessage As Label = CType(LabelPlaceHolder.FindControl("lblMessage"), Label)
  37:         lblMessage.ForeColor = Drawing.Color.Black
  38:         System.Diagnostics.Trace.WriteLine("Page_Init " & Now())
  39:     End Sub
  40:  
  41:     Protected Sub Page_InitComplete(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.InitComplete
  42:         ' Use this event for processing tasks that require all initialization be complete.
  43:         Dim ContentPlaceHolder1 As ContentPlaceHolder = CType(Master.FindControl("Main"), ContentPlaceHolder)
  44:         Dim LabelPlaceHolder As PlaceHolder = CType(ContentPlaceHolder1.FindControl("LabelPlaceHolder"), PlaceHolder)
  45:         Dim lblMessage As Label = CType(LabelPlaceHolder.FindControl("lblMessage"), Label)
  46:         lblMessage.ToolTip = "Tooltip added during InitComplete event."
  47:         ' Set a value in the viewstate
  48:         Me.ViewState("Author") = "Robert S. Robbins"
  49:         System.Diagnostics.Trace.WriteLine("Page_InitComplete " & Now())
  50:     End Sub
  51:  
  52:     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  53:         ' Use the OnLoad event method to set properties in controls and establish database connections.
  54:         Dim cn As New SqlConnection
  55:         Dim objSqlCommand As New SqlCommand
  56:         cn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings("Northwind").ToString()
  57:         cn.Open()
  58:         objSqlCommand.Connection = cn
  59:         objSqlCommand.CommandText = "SELECT ProductID, ProductName, UnitPrice FROM Products ORDER BY ProductName"
  60:         Dim objDataSet As DataSet = New DataSet()
  61:         Dim objSqlDataAdapter As SqlDataAdapter = New SqlDataAdapter()
  62:         objSqlDataAdapter.SelectCommand = objSqlCommand
  63:         objSqlDataAdapter.Fill(objDataSet)
  64:         GridView1.DataSource = objDataSet
  65:         GridView1.DataBind()
  66:         cn.Close()
  67:         System.Diagnostics.Trace.WriteLine("Page_Load " & Now())
  68:     End Sub
  69:  
  70:     Protected Sub Page_LoadComplete(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LoadComplete
  71:         ' Use this event for tasks that require that all other controls on the page be loaded.
  72:         ' Example: Get data from a GridView row after databinding has occurred.
  73:         System.Diagnostics.Trace.WriteLine(GridView1.Rows.Item(5).Cells(1).Text, "Row 6, Cell 2")
  74:         System.Diagnostics.Trace.WriteLine("Page_LoadComplete " & Now())
  75:     End Sub
  76:  
  77:     Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
  78:         ' Check the IsPostBack property to determine whether this is the first time the page is being processed.
  79:         If Page.IsPostBack = False Then
  80:             ' Create or re-create dynamic controls.
  81:             Dim lblMessage As New Label
  82:             lblMessage.ID = "lblMessage"
  83:             lblMessage.Width = 500
  84:             lblMessage.Text = "Dynamically created control."
  85:             Dim ContentPlaceHolder1 As ContentPlaceHolder = CType(Master.FindControl("Main"), ContentPlaceHolder)
  86:             Dim LabelPlaceHolder As PlaceHolder = CType(ContentPlaceHolder1.FindControl("LabelPlaceHolder"), PlaceHolder)
  87:             LabelPlaceHolder.Controls.Add(lblMessage)
  88:         End If
  89:         System.Diagnostics.Trace.WriteLine("Page_PreInit " & Now())
  90:     End Sub
  91:  
  92:     Protected Sub Page_PreLoad(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreLoad
  93:         ' Use this event if you need to perform processing on your page or control before the Load event.
  94:         ' Viewstate should be available now because it has been loaded.
  95:         System.Diagnostics.Trace.WriteLine(Me.ViewState.Values.Count, "ViewState Count")
  96:         ' The Request object should be available now. 
  97:         System.Diagnostics.Trace.WriteLine(Request.ServerVariables("SCRIPT_NAME"), "Script Name")
  98:         System.Diagnostics.Trace.WriteLine("Page_PreLoad " & Now())
  99:     End Sub
 100:  
 101:     Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
 102:         ' Use the event to make final changes to the contents of the page or its controls.
 103:         Dim ContentPlaceHolder1 As ContentPlaceHolder = CType(Master.FindControl("Main"), ContentPlaceHolder)
 104:         Dim GridView1 As GridView = CType(ContentPlaceHolder1.FindControl("GridView1"), GridView)
 105:         Dim objGridViewRow As GridViewRow
 106:         objGridViewRow = New GridViewRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal)
 107:         Dim objTableCell As TableCell = New TableCell()
 108:         Dim literal As LiteralControl = New LiteralControl()
 109:         literal.Text = "Northwind Products"
 110:         objTableCell.Controls.Add(literal)
 111:         objTableCell.ColumnSpan = 3
 112:         objTableCell.HorizontalAlign = HorizontalAlign.Center
 113:         objTableCell.ForeColor = Drawing.Color.White
 114:         objTableCell.BackColor = Drawing.Color.Black
 115:         objGridViewRow.Cells.Add(objTableCell)
 116:         GridView1.Controls(0).Controls.AddAt(0, objGridViewRow)
 117:         System.Diagnostics.Trace.WriteLine("Page_PreRender " & Now())
 118:     End Sub
 119:  
 120:     Protected Sub Page_PreRenderComplete(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRenderComplete
 121:         ' At this stage of the page life cycle, all controls are created, any pagination required is completed, and the page is ready to render to the output.
 122:         ' Example: The column headings of the gridview should be accessible now.
 123:         Dim ContentPlaceHolder1 As ContentPlaceHolder = CType(Master.FindControl("Main"), ContentPlaceHolder)
 124:         Dim GridView1 As GridView = CType(ContentPlaceHolder1.FindControl("GridView1"), GridView)
 125:         GridView1.HeaderRow.Cells(0).Text = "Product ID"
 126:         GridView1.HeaderRow.Cells(1).Text = "Product Name"
 127:         GridView1.HeaderRow.Cells(2).Text = "Unit Price"
 128:         ' Get the rendered HTML
 129:         'Dim objStringBuilder As New StringBuilder()
 130:         'Dim objStringWriter As New StringWriter(objStringBuilder)
 131:         'Dim objHtmlTextWriter As New HtmlTextWriter(objStringWriter)
 132:         'Me.RenderControl(objHtmlTextWriter)
 133:         'Dim strGridViewHTML As String = objStringBuilder.ToString()
 134:         'System.Diagnostics.Trace.WriteLine(strGridViewHTML)
 135:         System.Diagnostics.Trace.WriteLine("Page_PreRenderComplete " & Now())
 136:     End Sub
 137:  
 138:     Protected Sub Page_SaveStateComplete(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SaveStateComplete
 139:         ' Use this event perform tasks that require view state to be saved, but that do not make any changes to controls.
 140:         ' Example: Lets store some extraneous information in the view state
 141:         Me.ViewState("Date") = Now()
 142:         System.Diagnostics.Trace.WriteLine("Page_SaveStateComplete " & Now())
 143:     End Sub
 144:  
 145:     Protected Sub Page_Unload(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Unload
 146:         ' Use this event to do final cleanup work, such as closing open files and database connections, or finishing up logging or other request-specific tasks.
 147:         System.Diagnostics.Trace.WriteLine(Me.ViewState.Values.Count, "ViewState Count")
 148:         System.Diagnostics.Trace.WriteLine("Page_Unload " & Now())
 149:     End Sub
 150: End Class

 

More Posts Next page »