Introduction
This article is about loops and arrays. While I am covering a very basic skill; I truly believe that it is one that is under emphasized. I have read quite a few books on programming, and have never seen one with a chapter on using loops and arrays together. I was thinking about this the other day, and find it absolutely ludicrous... So I decided to write this article as a tutorial for beginning C# developers, and VB.NET developers learning C#.
The fact is that the ability to effectively use loops and arrays together is critical. The proper use of these tools gives the developer the following benefits:
- Accomplish your tasks using fewer lines of code.
- Make possible tasks that otherwise wouldn't be.
- Write more elegant code.
- And above all, this is a powerful way to manipulate data.
The example I am going to use to demonstrate this technique is a user control that creates a dynamic navigation bar I developed for a website. I feel it fits the topic well because while there may be other techniques to achieve the same result, this one is my favorite. So what I'll do is post the whole class and step though it explaining what's going on in each block.
This is the beginning of the class. I don't want to spend too much time here. You probably recognize the using statements at the top. They are referencing namespaces the class is using. Just make note that I am calling the MakeLinks() method in the page load event. I did this because I plan to move the method itself into a class library. Anyway.. it's being called on page load.
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
public partial class DynamicSideNav : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
MakeLinks();
}
Here I am setting up the information I am going to pass into the code, and I am also storing it is a session variable to carry it across pages. What I am doing is getting the URL using the Request.Url.ToString() method which returns the URL as a string and then I am checking it with the Contains(string) method to see what page I'm on. Then depending which page I'm on, I am assigning a numeric value to the session variable. Then if I am on a page that I don't want to pass anything to the code, I assign the Session variable a value of null.
protected void MakeLinks()
{
if (Request.Url.ToString().Contains("admin") != true)
{
string url = Request.Url.ToString();
if (url.Contains("men") == true)
{
Session["pID"] = "2";
}
if (url.Contains("lady") == true)
{
Session["pID"] = "3";
}
if (url.Contains("plus") == true)
{
Session["pID"] = "4";
}
if (url.Contains("wholesale") == true)
{
Session["pID"] = "7";
}
if (url.Contains("default") == true |
url.Contains("shoppingcart") == true |
url.Contains("account") == true |
url.Contains("checkoutpayment") == true |
url.Contains("paymentmethod") == true |
url.Contains("checkoutreview") == true)
{
Session["pID"] = null;
}
First, I am declaring my counter and an array of HyperLink controls. (Pay close attention to the counter "iRdr" because it will be doing a lot of the work.) Then I am checking the session variable to see if its value is null, if false, the code runs. Then I am pulling a data reader from the database. Notice I am concatenating the value of the session variable into the query string. This is how I am returning the information from the database I will use to build my hyperlinks in my nav bar.
int iRdr = 0;
HyperLink[] hyperLink = new HyperLink[0];
if (Session["pID"] != null)
{
CDataAccess objDB = new CDataAccess();
string sql = "SELECT CategoryID, Name, SEName
FROM Category WHERE ParentCategoryID=" +
(string)Session["pID"] + "";
string conn =
System.Configuration.ConfigurationManager.AppSettings["DBConn"];
SqlDataReader rdr1 = objDB.GetDataReader(conn, sql);
SqlDataReader rdr2 = objDB.GetDataReader(conn, sql);
This first loop simply counts the records returned from the database so we know how many links to create. Then I use the number of records determined by the counter to determine how many items will be there in the three string arrays just below. These three arrays will be used to set the properties of the hyperlink controls in my array of hyperlink controls.
while (rdr1.Read())
{
iRdr += 1
}
string[] catID = new string[iRdr];
string[] name = new string[iRdr];
string[] seName = new string[iRdr];
First I set my counter back to 0 because it will be used to assign values to the array. Now that I have arrays that hold the exact number of items I need, I use a loop to assign the values from each row of the data reader to the items in the array. Then close the reader, of course.
iRdr = 0;
while (rdr2.Read())
{
catID[iRdr] = rdr["CategoryID"].ToString();
name[iRdr] = rdr["Name"].ToString();
seName[iRdr] = rdr["SEName"].ToString();
iRdr += 1;
}
rdr.Colse();
Now it's time to create our dynamic hyperlinks. First I set number of hyperlinks in the hyperlink array with the counter. The first literal control is used to write the opening <table> tag for the table that will lay out our hyperlinks in a vertical line for the left nav bar. Then I start a for loop for my iRdr counter to determine the number of times the loop runs (again the number of links I'm creating based on the number of items returned from the database). The next creates the opening <tr> and <td> tags:
HyperLink[] _hyperLink = new HyperLink[iRdr];
hyperLink = _hyperLink;
Literal litB = new Literal();
litB.ID = "litB";
litB.Text = "<table1 align='center'>";
Controls.Add(litB);
for (int i = 0; i <= (iRdr - 1); i++)
{
Literal lit1 = new Literal();
lit1.ID = "lit1" + i;
lit1.Text = "<tr1><td1>";
Controls.Add(lit1);
Now here is where we bring everything together and create our hyperlinks. First we create a new hyperlink control. Then assign an id to the control using to counter to give each control a unique id. Then set the font size and color, make the link visible and enabled. Then we set the text property to the name stored in the name string array and use the counter to increment the array. Then we do the same with the NavigateUrl property again using the counter to increment the array. Then I add the control to Hyperlink array of controls again using the counter to increment. Then the control is added to the page. This may be the most important concept in this article. Use the counter to increment the arrays in your loop.
HyperLink hl = new HyperLink();
hl.ID = "hl" + i;
hl.Font.Size = System.Web.UI.WebControls.FontUnit.Larger;
hl.ForeColor = System.Drawing.Color.White;
hl.Visible = true;
hl.Enabled = true;
hl.Text = name[i];
hl.NavigateUrl = "~/c-" + catID[i] + "-" + seName[i] + ".aspx";
hyperLink[i] = hl;
Controls.Add(hyperLink[i]);
These next two literals create the closing </td>, </tr>, and </table> tags.
Literal lit2 = new Literal();
lit2.ID = "lit2" + i;
lit2.Text = "</tr1><td1>";
Controls.Add(lit2);
}
Literal litC = new Literal();
litC.ID = "litC";
litC.Text = "</table1>";
Controls.Add(litC);
}
You may have been wondering why we put out hyperlinks in an array when we were creating them on the fly. Well here is your answer. Easy destruction... Remember if there is no value in the session variable, all the above code is skipped and any existing hyperlinks are destroyed.. In one line of code "hyperLink = null;".
else
{
hyperLink = null;
}
}
}
}
Well, that's it. Happy coding!
History
- 29th September, 2007: Initial post