immEmr
immEmr

Reputation: 1

back track variable in C# recursive function

I have this data in same sql table. I need to create a tree look like structure for the following data. Everything seems to be working fine except the indenting is not working right. I am missing something minor which I am not able to figure out. I will appreciate any help.

This is data in same table

initiated_by
---------------------
 NULL,42521,42521,41651,41111,41111,41131,41651

user_id (assigned to)
---------------------
42521,41651,42681,41111,42021,41131,42001,43001

What I expecting is as follow.

42521 (at level 0)
   41651 (at level 1)
      41111 (at level 2)
        42021(at level 3)
        41131(at level 3)
          42001(at level 4)
      43001(at level 2)
   42681 (at level 1)

But what I am getting is not right. I am not able to figure out the indentLevel part. indentLevel is a variable declared at class level.

private void BuildTable(DataTable recordList)
    {
        foreach (DataRow dr in recordList.Rows)
        {

            TableRow tblRow = new TableRow();
            TableCell tblCell = new TableCell();

            tblCell.Controls.Add(GetDetailTable(dr, indentLevel));

            tblCell.HorizontalAlign = HorizontalAlign.Left;
            tblRow.Cells.Add(tblCell);
            mainTable.Rows.Add(tblRow);

            //Do we have any child objects
            int cId = Convert.ToInt32(dr["user_id"].ToString());
            DataTable dt = GetChildObjects(Convert.ToInt32(dr["user_id"].ToString()), masterDT);

            if (dt.Rows.Count > 0) indentLevel = indentLevel+1; BuildTable(dt);

        }

    }


    private Table GetDetailTable(DataRow dr, int indentLevel)
    {

        Table DetailTable = new Table();
        DetailTable.Width = Unit.Percentage(100);
        DetailTable.CssClass = "SortableTable";

        TableRow tblRow = new TableRow();

        TableCell tblEmptyCell = new TableCell();
        tblEmptyCell.Width = Unit.Percentage(5);
        tblEmptyCell.Controls.Add(new LiteralControl(string.Empty));
        tblEmptyCell.Width = Unit.Percentage(5 * indentLevel);  
        tblRow.Cells.Add(tblEmptyCell);

        //To Display Name
        TableCell tblCell = new TableCell();
        tblCell.Width = Unit.Percentage(15);
        tblCell.CssClass = "alt-row-hover";
        LiteralControl lc = new LiteralControl(dr["user_id"].ToString());

        tblCell.Controls.Add(lc);
        tblCell.HorizontalAlign = HorizontalAlign.Left;
        tblRow.Cells.Add(tblCell);
        mainTable.Rows.Add(tblRow);

        //To Display Detials
        TableCell tblCellDetials = new TableCell();
        tblCellDetials.CssClass = "alt-row";
        tblCellDetials.Width = Unit.Percentage(80);

        StringBuilder detailString = new StringBuilder();
        detailString.Append("Action: " + Convert.ToString(dr["action_id"]) + "<br>");
        detailString.Append("Action Date: " + Convert.ToString(dr["action_date"]) + "<br>");
        detailString.Append("Comments: " + Convert.ToString(dr["comments"]) + "<br>");

        LiteralControl lcd = new LiteralControl(detailString.ToString());

        tblCellDetials.Controls.Add(lcd);
        tblCellDetials.HorizontalAlign = HorizontalAlign.Left;
        tblRow.Cells.Add(tblCellDetials);


        DetailTable.Rows.Add(tblRow);


        return DetailTable;

    }
}

Upvotes: 0

Views: 291

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500595

You don't have anything which decrements indentLevel at the end of BuildTable.

Personally, I would change BuildTable to take the indentLevel as well, and just change this:

if (dt.Rows.Count > 0) indentLevel = indentLevel+1; BuildTable(dt);

to this:

if (dt.Rows.Count > 0)
{
    BuildTable(dt, indentLevel + 1);
}

Then just call it initially with:

BuildTable(rootTable, 0);

... and remove the instance variable completely. That way you don't need to decrement indentLevel at all; each nested call will just naturally get the right level.

By the way, C# isn't line-based when it comes to blocks - so currently your code is equivalent to:

// Current code
if (dt.Rows.Count > 0)
{
    indentLevel = indentLevel + 1;
}
BuildTable(dt, indentLevel);

That won't actually do any harm in this particular case, as the method does nothing when dt.Rows is empty, but it means your code is somewhat confusing. Personally I prefer to always use braces.

Upvotes: 4

Related Questions