Olav Wik Gundersen Olav Wik Gundersen - 1 month ago 5
C# Question

Defining and populating TableCells with Array?

I'm trying to define a TableCell Array, but are having some problems.
My code is as follows

public partial class ShowGoalsUserControl : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
SPWeb _web = SPContext.Current.Web;
SPList objGoalsList = _web.Lists["Goals"];

SPListItemCollection goalsItems = getItemsByQueryID(objGoalsList);

foreach (SPItem goalItem in goalsItems)
{
goalTitle.Text = "<h3>" + Convert.ToString(goalItem["Title"]) + "</h3>";
txtDescription.Text = Convert.ToString(goalItem["Description"]);

TableCell[] tc = new TableCell[9];

for (int i = 0; i < tc.Length; i++)
{
tc[i] = new TableCell();
}

tc[0].Text = "Status:";
setStatus(goalItem, tc[1], _web);

tc[2].Text = "Owner:";
SPFieldLookupValue thisOwner = getOwner(goalItem);
tc[3].Text = thisOwner.LookupValue;

tc[4].Text = "Perspective:";
SPFieldLookupValue thisPerspective = new SPFieldLookupValue(goalItem["Perspective"].ToString());
tc[5].Text = thisPerspective.LookupValue;

tc[6].Text = "Parent:";
SPFieldLookupValue thisParent = new SPFieldLookupValue(goalItem["Parent"].ToString());
tc[7].Text = thisParent.LookupValue;

tc[8].Text = "Deadline:";
tc[9].Text = Convert.ToString(goalItem["Deadline"]);

TableRow[] tr = new TableRow[4];

for (int p = 0; p < tr.Length; p++)
{
tr[p] = new TableRow();
}

setTableRow(tc[0], tc[1], tr[0]);
setTableRow(tc[2], tc[3], tr[1]);
setTableRow(tc[4], tc[5], tr[2]);
setTableRow(tc[6], tc[7], tr[3]);
setTableRow(tc[8], tc[9], tr[4]);

addToTable(tr);

}
}

SPListItemCollection getItemsByQueryID(SPList list)
{
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name='ID' /><Value Type='Text'>" + Request.QueryString["gid"] + "</Value></Eq></Where>";
SPListItemCollection items = list.GetItems(query);
return items;
}

void setStatus(SPItem item, TableCell status, SPWeb web)
{
string statusTest = Convert.ToString(item["Status"]);

switch (statusTest)
{
case "Approved":
status.Text = "<img src='" + web.Site.Url + "/_layouts/images/kpidefaultlarge-0.gif' height='10' width='10' />";
break;

case "Pending":
status.Text = "<img src='" + web.Site.Url + "/_layouts/images/kpidefaultlarge-1.gif' height='10' width='10' />";
break;

case "Declined":
status.Text = "<img src='" + web.Site.Url + "/_layouts/images/kpidefaultlarge-2.gif' height='10' width='10' />";
break;
}
}

SPFieldLookupValue getOwner(SPItem item)
{
SPFieldLookupValue getThisOwner = new SPFieldLookupValue(item["Owner"].ToString());
return getThisOwner;
}

void setTableRow(TableCell add1, TableCell add2, TableRow row)
{
row.Cells.Add(add1);
row.Cells.Add(add2);
}

void addToTable(TableRow[] tableRow)
{
for (int i = 0; i < tableRow.Length; i++)
{
infoTable.Rows.Add(tableRow[i]);
}

}

}


When I try to run this on the site I get the following error:


  Index was outside the bounds of the array.

  Description: An unhandled exception occurred during the
execution of the current web request.
Please review the stack trace for more
information about the error and where
it originated in the code.

  Exception Details: System.IndexOutOfRangeException: Index
was outside the bounds of the array.


What am I doing wrong? Is there any better way to do it?
Any comments would be helpful!

EDIT: tc[3] changed to tc[2]
EDIT2: Posted full code

Answer

The condition in your for loop doesn't make sense. With an array of three elements, it runs only two times. Because of this, the third element in your array (tc[2]) is null, because it never gets a value assigned to it. The same goes for your second loop.

Use this instead:

for (int p = 0; p < tc.Length; p++)

BTW: The last line of your example will throw an exception:

setTableRow(tc[2], tc[3], tr[1]);

tc[3] is the fourth element in an array of three items. This will result in an IndexOutOfRangeException.

UPDATE:
After you posted your full code, I can say this:

The following lines cause a IndexOutOfRangeException:

tc[9].Text = Convert.ToString(goalItem["Deadline"]);

setTableRow(tc[8], tc[9], tr[4]);

You created an array with 9 elements, i.e. with indexes 0 through 8. tc[9] tries to access the 10th element in an array of 9! To fix that problem, increase the size of your array to 10:

TableCell[] tc = new TableCell[10];

Additionally, you have the same problem with your TableRow array, so you should increase its size, too:

TableRow[] tr = new TableRow[5];