ProgTalk - Your archive for all source code

GridView control to show master-child or master-slave data, written in c#, asp.net, and javascript.

ProgTalk » Articles » .NET, C#, ASP.NET » GridView control to show master-child or master-slave data, written in c#, asp.net, and javascript.
 
Author: Rajib A.
Page Views: 58965
Average Article Rating: rating starrating starrating starrating starthree quarter star
 



PRE-REQUISITE
:

I previously made a master slave datagrid using Visual Studio 2003 .Net (original article) that would allow users to show data to clients using collapse and expand features.  These features however did not carry over to gridview for many users.  This tutorial will explaing how to create a collapsable/expandable gridview in frameworks 2.0 and higher.  If you have never seen the previous article, then just read the comments throughout to understand the code flow.  To use the provided source code, you will need the Northwind database.  If you do not have it, you can get it from here.



SCREENSHOTS:

Default screen of how grid view looks:

 


Expanding rows of the gridview:




Raising an event ouside of the gridview keeps expanded and collapse states:




Sample paging of the gridview:




Sample of expanding a row in the new page:






CHANGES:
The datagrid and gridview have many different methods.  When we used the datagrid, we had modified the ItemDataBound method using the ItemIndex.  This will be modified to use the RowDataBound method with the RowIndex objects.  We all dealt with columns that would have the primary keys of our Northwind Database tables.  When using ItemDataBound with the datagrid, the cells would have access to these contents, however with the gridview this is not achievable if the columns are marked with Visible = false;
We will also modify the paging and sorting with respect to our gridview.



WHAT STEPS ARE NEEDED TO MAKE A MASTER/SLAVE GRIDVIEW (HGRID):

Steps:

1.                  Add a gridview

2.                  Configure gridview and make sure first column has Hyperlink field with text as [+].

3.                  Configure other column along with the ID fields you need for your child/slave data.

4.                  Add link to the js file provided by this example using the standar ");
            }

         }

      }

   }

}

 



Next we will define the events of what is in our hidden textbox, which contains all the expanded rows information.
This information is delimeted by a comma, which we can later parse.



protected
void ButtonSample_Click(object sender, System.EventArgs e)

{

   LabelPostBack.ForeColor = System.Drawing.Color.DarkRed;

 

   if (txtExpandedDivs.Text.Length == 0)

   {

      LabelPostBack.Text = "A Postback has occurred. txtExpandedDivs has no content!";

   }

   else

   {
      LabelPostBack.Text = "A Postback has occurred. txtExpandedDivs has contents:
"

         
this.txtExpandedDivs.Text + "";

   }

}




 

The following below will define all our database methods.  Here we will see how to bind and query from our database.


Here we will do a simple query to fetch data from our Northwin database.  A stored procedure can also be called here, but for
simplicity, we will keep it here.


#region Database Methods

private
void BindData()

{

   //========Query For Master Rows===

   string QueryString = "SELECT OrderID, CustomerID, EmployeeID, ShipName as Name, "
         "ShipAddress as Address, "
         "ShipCity as City, "
         "ShipRegion as Region, ShipPostalCode as Postal, ShipCountry as Country FROM Orders"
;

 

   if (ViewState["sortby"] != null)

   {

      QueryString = QueryString + " order by " +

         ViewState["sortby"].ToString();

   }

   //==============================

 

   System.Data.SqlClient.SqlConnection conn = new

                  System.Data.SqlClient.SqlConnection();

 

   try

   {

      conn.ConnectionString = connectionstring;

      if (conn.State == System.Data.ConnectionState.Closed)

      {

         conn.Open();

      }

 

      System.Data.SqlClient.SqlDataAdapter adapter =

new System.Data.SqlClient.SqlDataAdapter(QueryString, conn);

 

      DataSet ds = new DataSet();

      adapter.Fill(ds);

      GridView1.DataSource = ds;

      GridView1.DataBind();

   }

   catch (Exception ex1)

   {

      Response.Write("An error has occurred: ");

      Response.Write(ex1.Message.ToString());

      Response.End();

   }

   finally

   {

      if (conn.State == System.Data.ConnectionState.Open)

      {

         conn.Close();

      }

   } 

}






The RunQuery method will simpley open a connection to the database, perform a query, and return the result to a dataset.
If you are using a database other than MSSQL, this method will need to change.  As you can see we are using teh SqlClient
which will not work with MySQL or Oracle databases.

 

private DataSet RunQuery(string QueryString)

{

   System.Data.SqlClient.SqlConnection conn = new

                  System.Data.SqlClient.SqlConnection();

 

   try

   {

      conn.ConnectionString = connectionstring;

      if (conn.State == System.Data.ConnectionState.Closed)

      {

         conn.Open();

      }

 

      System.Data.SqlClient.SqlDataAdapter adapter = new

                  System.Data.SqlClient.SqlDataAdapter(QueryString, conn);

 

      DataSet ds = new DataSet();

      adapter.Fill(ds);

      return ds;

   }

   catch (Exception ex1)

   {

      Response.Write("An Error has occurred.
"
);

      Response.Write(ex1.Message.ToString());

      Response.End();

      //This line below will never execute.

      return null;

   }

   finally

   {

      if (conn.State == System.Data.ConnectionState.Open)

      {

         conn.Close();

      }

   }

}

 

#endregion

 

#region GridView Methods

 




The RowDataBound method will perform the details query from the Northwind Database.  First we will check if the current row type is a data row.  If it is a data
row, we will look up the id columns using the e.Row.Cell[#].Text and pass it in for our subquery.  You can think of it in simpler terms.  Imagine we have two
tables ( User and Address)
The first table is a user table, and another is an Address table for all the addresses a user has lived in.  The main query in the BindData would handle all the records
from the User table.  The RowDataBound method fetch all the addresses from the Address table based on the user.
 

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)

{

   //If your page size is 10, 
   
//only 10 sub queries will be done.

   if (e.Row.RowType == DataControlRowType.DataRow)

   {
      
string DetailsQuery = "SELECT C.CompanyName, OD.UnitPrice, OD.Quantity, OD.Discount, E.FirstName, E.LastName " +

                    "FROM [Order Details] as OD, [Customers] as C, [Orders] as O, [Employees] as E " +

                    "where OD.OrderID = O.OrderID and O.CustomerID = C.CustomerID and O.EmployeeID = E.EmployeeID and " +

                    "O.OrderID = '" + e.Row.Cells[1].Text + "' and " +

                    "C.CustomerID = '" + e.Row.Cells[2].Text + "' and " +

                    "E.EmployeeID = '" + e.Row.Cells[3].Text + "'";

 

 

      //Here I am grabbing the additional data and putting it

      //into mini datagrids...

      //If you wish to just use labels, or other controls,

      //just bind the data as you

      //wish, and render to html as I did.

      DataSet ds = this.RunQuery(DetailsQuery);

               

      GridView NewDg = new GridView();

      NewDg.AutoGenerateColumns = true;

      NewDg.Width = Unit.Percentage(100.00);

      NewDg.Font.Size = 8;

      NewDg.Font.Name = "Tahoma";

      NewDg.HeaderStyle.HorizontalAlign = HorizontalAlign.Left;

      NewDg.BorderColor = System.Drawing.Color.Black;

               

      if (ds == null || ds.Tables.Count == 0 || ds.Tables[0].Rows.Count == 0)

      {

         NewDg.ShowFooter = true;

      }

      
      NewDg.DataSource = ds;

      NewDg.DataBind();

 

      System.IO.StringWriter sw = new System.IO.StringWriter();

      System.Web.UI.HtmlTextWriter htw = new System.Web.UI.HtmlTextWriter(sw);

      NewDg.RenderControl(htw);

 

      string DivStart = "

                  e.Row.RowIndex.ToString() +

"' style='DISPLAY: none; HEIGHT: 1px;'>";

      
      
string DivBody = sw.ToString();

      string DivEnd = "

";

      string FullDIV = DivStart + DivBody + DivEnd;

 

      int LastCellPosition = e.Row.Cells.Count - 1;

      int NewCellPosition = e.Row.Cells.Count - 2;

 

      e.Row.Cells[0].ID = "CellInfo" +

                  e.Row.RowIndex.ToString();

 

      //Match color of div which we will expand base on row

      if (e.Row.RowIndex % 2 == 0)

      {

         //set to regular row style

         e.Row.Cells[LastCellPosition].Text = e.Row.Cells[LastCellPosition].Text + 
            "" + FullDIV;

      }

      else

      {

         //set to alternative row style

         e.Row.Cells[LastCellPosition].Text = e.Row.Cells[LastCellPosition].Text + 
            "" + FullDIV;

      }

                
      e.Row.Cells[0].Attributes["onclick"] = "HideShowPanel('uniquename"
         e.Row.RowIndex.ToString() + "'); ChangePlusMinusText('"
         e.Row.Cells[0].ClientID + "'); SetExpandedDIVInfo('"
         e.Row.Cells[0].ClientID + "','" + this.txtExpandedDivs.ClientID + 
         "', 'uniquename" + e.Row.RowIndex.ToString() + "');";


      e.Row.Cells[0].Attributes["onmouseover"] = "this.style.cursor='pointer'";

      e.Row.Cells[0].Attributes["onmouseout"] = "this.style.cursor='pointer'";

 

   }

}





The RowCreated method will be used to hide our columns which have data we do no with the user to see.
In this example, Row 1, Row 2, and Row 3 hold id fields which we do no want to display.  Here we just set the Visible property to false.
If we had set the visible property to false when using the wizard, our RowDataBound method would not be able to see the id's of the fields.

       

protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)

{

   //Hide ID columns from user

   if (e.Row.RowType == DataControlRowType.Header ||

                 e.Row.RowType == DataControlRowType.DataRow)

   {

      e.Row.Cells[1].Visible = false;

      e.Row.Cells[2].Visible = false;

      e.Row.Cells[3].Visible = false;

   }

}





When a new page is chosen, we will clear our textbox which holds all the expanded rows.  Next we will simply point to the new PageIndex,
and bind the data. 



       

protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)

{

   //clear expanded rows, this is a new page

   txtExpandedDivs.Text = "";

   BindData();

   GridView1.PageIndex = e.NewPageIndex;

   GridView1.DataBind();

}

 

#endregion

 

 




 

JAVASCRIPT METHODS:

Below I will show the javascript methods used to collapse and expand the the rows.



 

//This method will switch the plus to a minus and vice versa on the client side

function ChangePlusMinusText(PlusMinusCellID)

{

      try

      {           

            var PlusMinusCellObj = document.all(PlusMinusCellID);

            if ( PlusMinusCellObj != null )

            {

                  if ( PlusMinusCellObj.innerHTML == "[+]")

                  {

                        PlusMinusCellObj.innerHTML = "[-]";

                       

                  }

                  else

                  {

                        PlusMinusCellObj.innerHTML = "[+]";

                  }

            }

      }

      catch(e)

      {

            alert( "Error in ChangePlusMinusText Method: " + e);

      }

}




 

//After a postback occurs, this method will re-expand old data.

function ShowExpandedDivInfo(TextBoxIDOfExpandedDiv, DataGridID)

{

   try

   {

      var DIVTB = document.all(TextBoxIDOfExpandedDiv);

      if ( DIVTB != null )

      {    

         var data = DIVTB.value;

         if ( data != null && data.length > 0 && data != ",")

         {

            var SplitData = data.split(",");

                       

            //Temp variables

            var SplitDataOfArrayItem = "";

            var DivIdentifier = "";

            var PlusMinusCellIdentifier = "";

                       

            for ( var i = 0; i < SplitData.length; i++)

            {

               //Format of textbox data

               //NameOfDIV + "@" + PlusMinusCellID

               SplitDataOfArrayItem = SplitData[i].split("@");

               //Get the ID of the DIV section

               DivIdentifier = SplitDataOfArrayItem[0];

               //Get the ID of the Cell with the Plus or Minus showing collapsed or expanded state.

               PlusMinusCellIdentifier = SplitDataOfArrayItem[1];

                             

               if ( DivIdentifier != null && DivIdentifier.length > 0 )

               {

                  //Expand DIV Section

                  ShowPanel( DivIdentifier );

               }

                             

               if ( PlusMinusCellIdentifier != null && PlusMinusCellIdentifier.length > 0 )

               {

                  var PlusMinusCellObj = document.all(PlusMinusCellIdentifier);

                  if ( PlusMinusCellObj != null )

                  {

                     //We found the cell to expand

                     PlusMinusCellObj.innerHTML = "[-]";

                  }

                  else

                  {

                     //We DID NOT FIND the cell to expand

                     //May Have Been Lost After Postback.

                                         

                     //Invoke Method to get id of cell using partial data which will always

                     //be unique...

                     var NewPlusMinusCellObjID = getItem(PlusMinusCellIdentifier, DataGridID);

                                         

                     if ( NewPlusMinusCellObjID != null )

                     {

                        var NewCellObject = document.all(NewPlusMinusCellObjID);

                        if ( NewCellObject != null )

                        {

                           var rows = NewCellObject.getElementsByTagName("td");  

                           if ( rows != null && rows.length >= 0)

                           {

                              //the initial row has to be set to expanded....

                              try

                              {

                                 rows[0].innerHTML = "[-]";

                              }

                              catch(e)

                              {

                                 //alert("Error in setting row 
                                 //to expanded in ShowExpandedDivInfo Method.
                                 //Error 101: " + e);

                              }

                                                           

                           }//end of rows if statement

                        }//end of NewCellObject != null

                     }//end of NewPlusMinusCellObjID != null

                 }//end of PlusMinusCellObj != null if else

               }//end of PlusMinusCellIdentifier != null

            }//end of for loop

         }

      }

   }

   catch(e)

   {

      alert( "Error in ShowExpandedDivInfo Method: " + e);

   }

}


 




//This will keep the data in the hidden textbox field.

function SetExpandedDIVInfo(PlusMinusCellID, HiddenTextBoxToHoldDivInfo, DIVInfoID)

{

   try

   {

      var IsExpanded = false;

      var HTBObj = document.all(HiddenTextBoxToHoldDivInfo);

      var HLObj = document.all(PlusMinusCellID);

           

      if ( HLObj != null && HTBObj != null)

      {

           

         if ( HLObj.innerHTML == "[+]")

         {

            IsExpanded = false;    

         }

         else

         {

            IsExpanded = true;

         }

                             

         //What is in the hidden DIV Textbox field?

         var ExpandedData = HTBObj.value;

         

         if ( ExpandedData == null || ExpandedData == "," )

         {

            ExpandedData = "";

         }

                 

         //===============================================================

         if ( ExpandedData.length < 1 && IsExpanded == true )

         {

            //No Previous Expanded Data. 

            //Add new Expanded Field.

            ExpandedData = DIVInfoID + "@" + PlusMinusCellID;

            HTBObj.value = ExpandedData;

         }

         else if ( ExpandedData.length < 1 && IsExpanded == false )

         {

            //No Previous Expanded Data. 

            //Clean up old Expanded Field.

            //ExpandedData is empty, so no work is needed.

         }

                 

         else if ( ExpandedData.length > 0 && ExpandedData.indexOf(DIVInfoID) == -1 && IsExpanded == true )

         {

            //Expanded data has data from before.

            //No existing record exists for this field.

            //We can add new Expanded field.

            //We can use a comma as a delimeter.

            ExpandedData = ExpandedData + "," + DIVInfoID + "@" + PlusMinusCellID;

            ExpandedData = ExpandedData.replace( ",," , ",");

            HTBObj.value = ExpandedData;

         }

         else if ( ExpandedData.indexOf(DIVInfoID) > -1 && IsExpanded == true )

         {

            //Expanded data has data from before.

            //Existing record exists for this field.

            //We do not need to perform any updates.

         }

         else if ( ExpandedData.indexOf(DIVInfoID) > -1 && IsExpanded == false )

         {

            //Expanded data has data from before.

            //Existing record exists for this field

            //We remove it as it is not expanded any longer.

            ExpandedData = ExpandedData.replace(DIVInfoID  + "@" + PlusMinusCellID ,"");

                       

            //Make sure we don't have a double delimeter

            ExpandedData = ExpandedData.replace( ",," , ",");

            HTBObj.value = ExpandedData;

         }

         else if ( ExpandedData.indexOf(DIVInfoID) == -1 && IsExpanded == false )

         {

            //Expanded data has data from before.

            //Existing record does not exists for this field

            //No work is needed.

         }

                 

         //Recheck we don't have any garbage data.

         //Added because deleting items, causes a comma

         //to stay sometimes.

         if ( HTBObj != null && HTBObj.value == "," )

         {

            HTBObj.value = "";

         }

         //===============================================================

      }    

   }

   catch(e)

   {

      alert( "Error in SetExpandedDIVInfo Method: " + e);

   }

}

 





//This method will hide the panel.

function HidePanel(Panel)

{

   try

   {

      var ChosenPanel = document.all(Panel);

      if ( ChosenPanel != null )

      {

         document.all(Panel).style.display = "none";

      }

   }

   catch(e)

   {

      alert( "Error in HidePanel Method: " + e);

   }

}

 





//This method will show the panel. 

function ShowPanel(Panel)

{

   try

   {

      var ChosenPanel = document.all(Panel);

      if ( ChosenPanel != null )

      {

         document.all(Panel).style.display = "block";

      }

   }

   catch(e)

   {

      alert( "Error in ShowPanel Method: " + e);

   }

}

 




//This method will hide and show the panel.    

function HideShowPanel(Panel)

{

   try

   {

      var ChosenPanel = document.all(Panel);

      if ( ChosenPanel != null )

      {

         var currentdisplay = document.all(Panel).style.display;

         if ( currentdisplay != "block")

         {

            document.all(Panel).style.display = "block";

         }

         else

         {

            document.all(Panel).style.display = "none";

         }

      }

   }

   catch(e)

   {

      alert( "Error in HideShowPanel Method: " + e);

   }

}

 





//This method will get the object using partial id match.

function getItem(IDSearchCriteria, DataGridID)

{

   try

   {

      if ( IDSearchCriteria == null || IDSearchCriteria.length <= 0 )

      {

         return null;

      }

      else if ( DataGridID == null || DataGridID.length <= 0 )

      {

         return null;

      }

           

      if( document.getElementsByTagName )

      { 

         var table = document.getElementById(DataGridID);  

         if ( table != null )

         {

            var rows = table.getElementsByTagName("tr");  

            for ( var i = 0; i < rows.length; i++ )

            {

               var Identity = rows[i].id;

                             

               if ( Identity != null && Identity.length > 0 )

               {

               

                  var cellid = IDSearchCriteria.substring( IDSearchCriteria.lastIndexOf("_") + 1 );

                  if ( Identity.match(cellid) )

                  {

                     //alert("Found: " + Identity);

                     return Identity;

                  }

                                   

               }

            }

         }

         return null;     

      }

      else

      {

         return null;

      }

   }

   catch(e)

   {

      alert( "Error in getItem Method: " + e);

            return null;

   }

}



Leave some feedback.

 

Notes

The gridview has much more flexible methods than the datagrid. Though some methods are a bit different, it is just a simple html table once rendered. Keeping this in mind, we can achieve any type of visual structure we desire.
 

Tags

Gridview, C#, Master Child, Parent Child
 

Ratings

Was this article helpful? Don't forget to rate it. Ratings helps community members identify top & useful articles.
Current Rating: rating starrating starrating starrating starthree quarter star
Rate this article:
(1-Poor, 2-Needs Improvement, 3-Average, 4-Good, 5-Excellent)
 

Feedback

Have a question, suggestion or feedback for this article? Leave your comments below.
Share your feedback:
Need to upload images with your comment. Upload your images here: Image Shack. Remember to copy the url of your uploaded image and insert it into the comment.
You can insert images by clicking on the following icon: insert comment image
(Members Only)
 

Latest Comments

Below are the latest comments from other ProgTalk members.
Posted on:
6/24/2010 1:04:54 AM
Posted by:
Hi Rajib,

Have  look at the below url.  I am facing displying issue with Detail data.  Could you please help.
http://img35.imageshack.us/img35/9045/displayissue.jpg


My aspx file code is:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ucRuleTransHistory.ascx.cs" Inherits="LeggMason.FundSpace.Maintenance.Presentation.UserControls.ucRuleTransHistory" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>

<link href="../StyleSheets/FundSpaceMain.css" rel="stylesheet" type="text/css" />

<script type="text/javascript" src="/JavaScript/HGridScript.js"></script>

<TABLE id="Table1" height="1" cellSpacing="0" cellPadding="0" width="100%" border="0">

<TR>

<TD noWrap align="left"><asp:label id="LabelTitle" runat="server" Font-Size="8pt" Font-Names="Tahoma" Font-Bold="True"

ForeColor="Blue">NORTHWIND ORDERS</asp:label><br />

<asp:Label ID="Label1" runat="server" Font-Bold="True" Font-Names="Tahoma" Font-Size="8pt"

ForeColor="Blue">Click on the [+] to view details of the order.</asp:Label></TD>

</TR>

<TR>

<TD noWrap align="left">

&nbsp;<asp:GridView ID="GridTransactions" runat="server" AllowPaging="True" AutoGenerateColumns="True"

CellPadding="4" Font-Names="Tahoma" Font-Size="8pt" ForeColor="#333333" GridLines="None"

OnRowDataBound="GridTransactions_RowDataBound">

<FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />

<Columns>

<asp:HyperLinkField Text="[+]" />

</Columns>

<RowStyle BackColor="#EFF3FB" />

<EditRowStyle BackColor="#2461BF" />

<SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />

<PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />

<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />

<AlternatingRowStyle BackColor="White" />

</asp:GridView>

</TD>

</TR>

<TR>

<TD noWrap align="left">

<P><asp:button id="ButtonSample" runat="server" Font-Size="8pt" Font-Names="Tahoma" Text="What happens during a postback?" onclick="ButtonSample_Click"></asp:button><asp:textbox id="txtExpandedDivs" runat="server" Font-Size="8pt" Font-Names="Tahoma" Width="0px"></asp:textbox></P>

</TD>

</TR>

<TR>

<TD style="HEIGHT: 2px" noWrap align="left"><asp:label id="LabelWhatHappens" runat="server" Font-Size="8pt" Font-Names="Tahoma" Font-Bold="True"

Width="100%">What are we storing in the hidden textbox field (txtExpandedDivs TextBox Control)?</asp:label></TD>

</TR>

<TR>

<TD noWrap align="left"><asp:label id="LabelPostBack" runat="server" Font-Size="8pt" Font-Names="Tahoma" Width="100%"></asp:label></TD>

</TR>

</TABLE>


Posted on:
1/12/2010 8:44:49 AM
Posted by:

It seems that whenever I try to add a server control in a field (just about any column not retrieved from the server), the rows won't expand. Anyone else seen this? Anyone know a fix?
I would like the first or last column to be a select column enabling the user to select it and then be passed on in my program...

Anyone?

Posted on:
1/8/2010 5:41:29 AM
Posted by:

Hi Rajib,

I an getting javascript error in my browser when I click the [+] sign which turns to a [-] but not back to a [+].  Any ideas what the issue could be ??

Rgds

Posted on:
11/11/2009 7:04:18 AM
Posted by:
Hi there! I simply love your implementation however I have encountered a problem that I cannot quite figure out by myself. Let me show a screenshot of the problem on this url: http://img142.imageshack.us/img142/3379/problemwithgridview.png.
As you can see the "hidden" div have a height, which renders my gridview uneven.
My table should be correctly rendered as the resulting div looks like this:
<div id="uniquename3" style="display: none; height: 0px;">
I have tried to remove height: 0px as you described in earlier posts with any luck. Any ideas?

Posted on:
11/11/2009 7:45:52 AM
Posted by:
Actually, after a postback on the page, the page looks normal as intended. However, clicking the [+] only changes the [+] to [-] but it does not expand/collaps the details. Any idea about what I did wrong?
Posted on:
9/3/2009 12:00:00 AM
Posted by:
Hi

Is there any way which i can drill down further from the child grid created.

Thanks
Roopesh
Posted on:
9/4/2009 12:00:00 AM
Posted by:
Hey Roopesh,

Drilling down becomes more of a headache.  what you would have to do is inside the div we create in the item databound, create another child div.  by setting it to a large width it'll automatically step to the next line.  use the style="margin-left: 25px" to push it to the right.  You would reuse the same logic, but create inner divs each time.  Get's more tricky with the javascript part tho.
Posted on:
9/4/2009 12:00:00 AM
Posted by:
Thanks Rajib, I will try in that way.
Posted on:
10/26/2009 4:34:40 PM
Posted by:
Hi Rajib

As we discussed previously i need total 3 levels drill down. Can you send me how we can create an inner div in existing div to place the 3rd child gridview.

Thanks
Roopesh
Posted on:
9/2/2009 12:00:00 AM
Posted by:
Hi,
Great article.
I want to Edit/Cancel to Child Grid. I read your reply in other posts also but it is not clear to me.
Please guide.
Pratiksha
Posted on:
9/4/2009 12:00:00 AM
Posted by:
Hey Pratiksha,

I'll try to clarify a bit further.  Currently this is the process we are doing:
1.  Getting parent rows
2.  Getting each child row for each parent row, building a grid, and ripping the html and placing it into the table row of the first grid.  Because we are placing regular html, the standard events that come from a grid are difficult to keep.  Usually what I do is build the child grid with an edit hyperlink which populates a pop up window for edit, or redirects to a different approach.  If we wanted to keep the features of the child grid, and have edit/cancel options, we would have to modify the code entirely.  Pretty much instead of ripping the html we would first create dynamic events, then add the grid as a control to the parent grid row.  This will allow proper viewstate and event registration.  Next, on page load you would have to recreate the grid and childrows to synch with the viewstate.  Then the automated events for edit and cancel would fire.  It is much more complex, and I would recommend the first apprach.

I hope this helps.  Sorry for the late reply.

Rajib
Posted on:
8/28/2009 12:00:00 AM
Posted by:
Hi Rajib,

Thanks man ! Excellent work. For me this works fine. Can I drill down to another child gridview from the child already created so total 3 levels.
Hope you understand my question.

Thanks,

Roopesh

Posted on:
8/27/2009 12:00:00 AM
Posted by:
Thanks Rajib!! Awesome piece of code.
Posted on:
6/23/2009 12:00:00 AM
Posted by:

Is there any way to get the child grid rows to handle the selected indexe changed event?

Thanks,

Jeff

Posted on:
9/4/2009 12:00:00 AM
Posted by:
Hey Jeff,

Sorry for the really late reply.  Using the selected index change event gets tricky.  Why not just create a link with the id and current page, and when the user clicks it go to the same url with that id?  This way on your page load you can check for the Request.QueryString["ChildID"] != null and process it accordingly.

Rajib
Posted on:
6/16/2009 12:00:00 AM
Posted by:
At first many thanks to Rajib for this great work!

Well, I need to use the grid with a master page and like some other people with some problems ...
At first I get some JS errors as document.all don''t work any more (funny as it works without master page structure) - so I just replace every document.all with document.getElementById  (most at HGridScript.js and if I''m right one at the code behind).
Ok, no more JS errors now ... But Firebug reports 38 (or 36?) more errors ...

So in DataGrid1_RowDataGround replace the lines after the line
//Match color of div which we will expand base on row
with this code:
            if (e.Row.RowIndex % 2 == 0)
            {
                //set to regular row style
                e.Row.Cells[LastCellPosition].Text = e.Row.Cells[LastCellPosition].Text + "</td></tr><tr><td bgcolor=''#EFF3FB'' colspan=''" + NewCellPosition + "''>" + FullDIV;
            }
            else
            {
                //set to alternative row style
                e.Row.Cells[LastCellPosition].Text = e.Row.Cells[LastCellPosition].Text + "</td></tr><tr><td bgcolor=''white'' colspan=''" + NewCellPosition + "''>" + FullDIV;
            }

Just a fistfull of warnings now but no more errors yet ...

I know about some more bugs as after a postback there''ll be no more change of +/- now until you change the page id.
But at all it seems to work with master page and ff3 and ie8 now and I hope it''ll help others to solve your problems...
Posted on:
6/4/2009 12:00:00 AM
Posted by:
do
How do I make the child gridview header with sort (asc or desc)?
Posted on:
9/4/2009 12:00:00 AM
Posted by:
I usually try to use a javascript sorting for the child grids. 
Take this resource, it is a client side approach to sorting.
http://yoast.com/articles/sortable-table/
Posted on:
6/3/2009 12:00:00 AM
Posted by:
do

Rajib,

I tried to follow your link on "Expand All" but I noticed that I have 100+ uniquename(1 thru 100+). Does that mean I have to pass all of the uniquename. Very confused. Can you please post what all I need in order to implement "Expand All" including aspx.cs and aspx page.

I would truly appreciated it. I am struglling with this for few days. Hope you understand.

Thanks
~ Do ~

======= original post ========
Posted By: Rajib
Posted Date: 12/15/2008
Message:


I think the javascript function would be:

function HideShowAll(divid)
{
    try
    {
        var j = 0;
        for( j = 0; j < 10; j++)
        {
            var dataid = divid + j;
            HideShowPanel(dataid);
        }
    }
    catch(e)
    {}
}

You would need to pass the generic div id which is uniquename, HideShowAll(''uniquename'');
Just view the source of your aspx page using mozilla or ie, and check what your div id''s are. 
It will be something likeuniquename1, uniquename2, etc...

Posted on:
5/26/2009 12:00:00 AM
Posted by:
Hi
Article is really great and this exactly the same am looking for.
But when i try implementing it , am facing problem in javascript

Sometimes it says "unidentified error''

and sometimes (after resetting iis), my debugger get stuck here in

ScriptResource.axd

var clientRects = element.getClientRects();
am facing error at getclientRects().
am using IE6 and in my aspx page am using master page.
please help me how to come out of this issue.

Regards
Usha



Posted on:
4/26/2009 12:00:00 AM
Posted by:
Pit
Hi,

I tried to convert it to VB code but I encounter Error under:

Protected Sub GridView2_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView2.RowDataBound
        ''If your page size is 10, only 10 sub queries will be done.
        If e.Row.RowType = DataControlRowType.DataRow Then

            Dim DetailsQuery As String = ("SELECT [JobNumber],[Customer],convert(char,[DateIn],105) as DateIn,[QRef],[Description],[Qty],[Status],[ManHour],[DeliveryOrder],[DO_Date],[Work_Order_Number],[MSCTEXP] ,[InvoiceNumber],[InvoiceDate],[Invoice_Percent],[DateIn_ISO] FROM [LamHeng].[dbo].[sqlJobNumberDetailed] where Project_Vessel = ''") + e.Row.Cells(3).Text & "''"


            ''Here I am grabbing the additional data and putting it into mini datagrids...
            ''If you wish to just use labels, or other controls, just bind the data as you
            ''wish, and render to html as I did.
            Dim ds As DataSet = Me.RunQuery(DetailsQuery)

            Dim NewDg As New GridView()
            NewDg.AutoGenerateColumns = True
            NewDg.Width = Unit.Percentage(100.0R)
            NewDg.Font.Size = 8
            NewDg.Font.Name = "Tahoma"
            NewDg.HeaderStyle.HorizontalAlign = HorizontalAlign.Left
            NewDg.BorderColor = System.Drawing.Color.Black

            If ds Is Nothing OrElse ds.Tables.Count = 0 OrElse ds.Tables(0).Rows.Count = 0 Then
                NewDg.ShowFooter = True
            End If
            NewDg.DataSource = ds
            NewDg.DataBind()

            Dim sw As New System.IO.StringWriter()
            Dim htw As New System.Web.UI.HtmlTextWriter(sw)
            NewDg.RenderControl(htw)

            Dim DivStart As String = "<DIV id=''uniquename" & e.Row.RowIndex.ToString() & "'' style=''DISPLAY: none; HEIGHT: 1px;''>"
            Dim DivBody As String = sw.ToString()
            Dim DivEnd As String = "</DIV>"
            Dim FullDIV As String = DivStart + DivBody + DivEnd
            Dim LastCellPosition As Integer = e.Row.Cells.Count - 1
            Dim NewCellPosition As Integer = e.Row.Cells.Count - 2
            e.Row.Cells(0).ID = "CellInfo" & e.Row.RowIndex.ToString()
            If e.Row.RowIndex Mod 2 = 0 Then
                ''set to regular row style
                e.Row.Cells(LastCellPosition).Text = ((e.Row.Cells(LastCellPosition).Text & "</td><tr><td bgcolor=''#EFF3FB''></td><td colspan=''") + NewCellPosition & "''>") + FullDIV
            Else
                ''set to alternative row style
                e.Row.Cells(LastCellPosition).Text = ((e.Row.Cells(LastCellPosition).Text & "</td><tr><td bgcolor=''white''></td><td colspan=''") + NewCellPosition & "''>") + FullDIV
            End If
            e.Row.Cells(0).Attributes("onclick") = (((("HideShowPanel(''uniquename" & e.Row.RowIndex.ToString() & "''); ChangePlusMinusText(''") + e.Row.Cells(0).ClientID & "''); SetExpandedDIVInfo(''") + e.Row.Cells(0).ClientID & "'',''") + Me.txtExpandedDivs.ClientID & "'', ''uniquename") + e.Row.RowIndex.ToString() & "'');"
            e.Row.Cells(0).Attributes("onmouseover") = "this.style.cursor=''pointer''"
            e.Row.Cells(0).Attributes("onmouseout") = "this.style.cursor=''pointer''"
        End If
    End Sub


The error message is: Conversion from string "17-04-2008                    </" to type ''Double'' is not valid.

any help please. Thanks a lot.

Posted on:
4/26/2009 12:00:00 AM
Posted by:
use this link for the vb.net version http://www.progtalk.com/ViewArticle.aspx?ArticleID=51
Posted on:
4/28/2009 12:00:00 AM
Posted by:
Hi

I did all of the above but still i am not able to expand the detail row. please find the snapshot below:

My ASPX Code is :

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="KeyMilestones.aspx.vb" Inherits="KeyMilestones" EnableEventValidation="false" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">

    <title>Project DashBoard - Airline Solutions</title>
    <link rel='stylesheet' type='text/css' href='styles/Dashboard.css' />
    <script language="javascript" src="JavaScript/HGridScript.js"></script>
</head>
<body>
    <form id="form1" runat="server">
         <table width="60%" class="DataTD">
            <tr>
                <td class="TDData">
                    Search for Project Information:</td>
                <td class="TDData" align="right">
                    Last Report Execution(s) :<asp:DropDownList ID="DropDownList1" runat="server">
                        <asp:ListItem>Apr 1 2009</asp:ListItem>
                        <asp:ListItem>Apr 15 2009</asp:ListItem>
                        <asp:ListItem>Apr 29 2009</asp:ListItem>
                    </asp:DropDownList></td>
            </tr>
            <tr>
                <td colspan="2" bgcolor="SteelBlue">
                </td>
            </tr>
           
             <tr>
                 <td align="right" class="TDData" colspan="2" valign="top">&nbsp;
                     <a href="javascript:hcolumns = window.open ('GridColumns.aspx','DisplayColumns','width=600,height=800');History.Go(-1);">
                    Show/Hide Column(s)</a>&nbsp;
                     <asp:Button ID="CmdFilter" runat="server" CssClass="DashButton" Text="Filter ON" /></td>
             </tr>
             <tr>
                 <td align="right" colspan="2" bgcolor="SteelBlue">
                 </td>
             </tr>
             <tr>
                 <td align="left" class="TDData" colspan="2">
                    <div style="width:910px; height: 75px; overflow-x: scroll">
                   
                    <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" CellPadding="4"
                        EnableTheming="False" Font-Names="Arial;Verdana" Font-Size="8pt" ForeColor="Black"
                        HorizontalAlign="Left" PageSize="5" SelectedIndex="0" ShowFooter="True" Height="60%" width="40%" AutoGenerateColumns="False">
                        <FooterStyle BackColor="SteelBlue" Font-Bold="True" ForeColor="White" />
                        <RowStyle BackColor="#F7F6F3" BorderStyle="Solid" ForeColor="#333333" HorizontalAlign="Left" />
                        <EmptyDataRowStyle Font-Size="8pt" />
                        <PagerStyle BackColor="SteelBlue" ForeColor="White" HorizontalAlign="Left" VerticalAlign="Bottom" />
                        <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
                        <HeaderStyle BackColor="SteelBlue" Font-Bold="True" Font-Names="Arial;Verdana" Font-Size="8pt"
                            ForeColor="White" HorizontalAlign="Center" VerticalAlign="Middle" />
                        <EditRowStyle BackColor="#999999" BorderWidth="1px" Font-Size="8pt" />
                        <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
                       
                        <Columns>
                            <asp:HyperLinkField Text="+" />                           
                            <asp:HyperLinkField
                            DataTextField="PR"
                            DataNavigateUrlFormatString='javascript:ywindow = window.open (&quot;DisplayPR.aspx&quot;,&quot;PRDisplay&quot;,&quot;width=1000,height=600&quot;, &quot;location=1,status=1,scrollbars=1&quot;);History.Go(-1);'
                            DataNavigateUrlFields="PR"
                            NavigateUrl='javascript:ywindow = window.open (&quot;DisplayPR.aspx&quot;,&quot;PRDisplay&quot;,&quot;width=1000,height=600&quot;,&quot;location=1,status=1,scrollbars=1&quot;);History.go(-1);'
                            HeaderText="PR" SortExpression="PR">
                                <ItemStyle Font-Names="Verdana" Font-Size="8pt" />                                                                                       
                                <ControlStyle Width="40px" />
                                </asp:HyperLinkField>             
                            <asp:BoundField DataField="Solution_Area" HeaderText="Solution_Area" SortExpression="Solution_Area" />
                            <asp:BoundField DataField="Product_Family" HeaderText="Product_Family" SortExpression="Product_Family" />
                            <asp:BoundField DataField="Product" HeaderText="Product" SortExpression="Product" />
                            <asp:BoundField DataField="Module_Name" HeaderText="Module_Name" SortExpression="Module_Name" />
                            <asp:BoundField DataField="Project_Type" HeaderText="Project_Type" SortExpression="Project_Type" />
                            <asp:BoundField DataField="Customer" HeaderText="Customer" SortExpression="Customer" >
                                <ItemStyle Wrap="True" />
                            </asp:BoundField>
                            <asp:BoundField DataField="Region" HeaderText="Region" SortExpression="Region" />
                            <asp:BoundField DataField="Delivery_Dir" HeaderText="Delivery_Dir" SortExpression="Delivery_Dir" />
                            <asp:BoundField DataField="Project_Status" HeaderText="Project_Status" SortExpression="Project_Status" />
                            <asp:BoundField DataField="Project_Mgr" HeaderText="Project_Mgr" SortExpression="Project_Mgr" />
                            <asp:BoundField DataField="Account_Mgr" HeaderText="Account_Mgr" SortExpression="Account_Mgr" />
                            <asp:BoundField DataField="Budget" HeaderText="Budget" SortExpression="Budget" />
                            <asp:BoundField DataField="ITD" HeaderText="ITD" SortExpression="ITD" />
                            <asp:BoundField DataField="Schedule_Barometer" HeaderText="Schedule_Barometer" SortExpression="Schedule_Barometer" />
                            <asp:BoundField DataField="Weeks_in_Barometer" HeaderText="Weeks_in_Barometer" SortExpression="Weeks_in_Barometer" />
                            <asp:BoundField DataField="Schedule_Comments" HeaderText="Schedule_Comments" SortExpression="Schedule_Comments" />
                            <asp:BoundField DataField="Project_Barometer" HeaderText="Project_Barometer" SortExpression="Project_Barometer" />
                            <asp:BoundField DataField="Original_Contract_Cutover_Date" HeaderText="Original_Contract_Cutover_Date"
                                SortExpression="Original_Contract_Cutover_Date" />
                            <asp:BoundField DataField="Last_Saved_Date" HeaderText="Last_Saved_Date" SortExpression="Last_Saved_Date" />
                            <asp:BoundField DataField="Budget_Breakdown" HeaderText="Budget_Breakdown" SortExpression="Budget_Breakdown" />
                            <asp:BoundField DataField="Value_Measurement_Established" HeaderText="Value_Measurement_Established"
                                SortExpression="Value_Measurement_Established" />
                            <asp:BoundField DataField="Project_Initiation_Phase_Complete" HeaderText="Project_Initiation_Phase_Complete"
                                SortExpression="Project_Initiation_Phase_Complete" />
                            <asp:BoundField DataField="Interactive_Pilot_Phase_Complete" HeaderText="Interactive_Pilot_Phase_Complete"
                                SortExpression="Interactive_Pilot_Phase_Complete" />
                            <asp:BoundField DataField="Installation_Partition_Complete" HeaderText="Installation_Partition_Complete"
                                SortExpression="Installation_Partition_Complete" />
                            <asp:BoundField DataField="Solution_Adoption_Phase_Complete" HeaderText="Solution_Adoption_Phase_Complete"
                                SortExpression="Solution_Adoption_Phase_Complete" />
                            <asp:BoundField DataField="Customer_Validation_Complete" HeaderText="Customer_Validation_Complete"
                                SortExpression="Customer_Validation_Complete" />
                            <asp:BoundField DataField="Customer_Training_Complete" HeaderText="Customer_Training_Complete"
                                SortExpression="Customer_Training_Complete" />
                            <asp:BoundField DataField="Cutover_Complete" HeaderText="Cutover_Complete" SortExpression="Cutover_Complete" />
                            <asp:BoundField DataField="Transition_to_Customer_Care_Complete" HeaderText="Transition_to_Customer_Care_Complete"
                                SortExpression="Transition_to_Customer_Care_Complete" />
                            <asp:BoundField DataField="Project_Transition_Phase_Complete" HeaderText="Project_Transition_Phase_Complete"
                                SortExpression="Project_Transition_Phase_Complete" />
                    </Columns>
                        <PagerSettings Position="TopAndBottom" />
                </asp:GridView>
                         </div>
                 </td>
             </tr>
             <tr>
                 <td align="right" colspan="2" bgcolor="SteelBlue">
                 </td>
             </tr>
             <tr>
                 <td align="left" class="TDData" colspan="2">
                    Showing 5 of 5 Records &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
                     &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
                     &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
                     &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
                     &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
                     &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
                     &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;
                    <asp:Button ID="Button2" runat="server" CssClass="DashButton" Text="Save As Excel" /></td>
             </tr>
            
             <TR>
                    <TD noWrap align="left">
                        <P><asp:button id="ButtonSample" runat="server" Font-Size="8pt" Font-Names="Tahoma" Text="What happens during a postback?"></asp:button>
                            <div style="DISPLAY: block; VISIBILITY: visible">
                                <asp:textbox id="txtExpandedDivs" runat="server" Font-Size="8pt" Font-Names="Tahoma" Width="400px"></asp:textbox>
                            </div>
                        <P></P>
                    </TD>
                </TR>
                                <TR>
                    <TD style="HEIGHT: 2px" noWrap align="left"><asp:label id="LabelWhatHappens" runat="server" Font-Size="8pt" Font-Names="Tahoma" Font-Bold="True"
                            Width="100%">What are we storing in the hidden textbox field (txtExpandedDivs TextBox Control)?</asp:label></TD>
                </TR>
                <TR>
                    <TD noWrap align="left"><asp:label id="LabelPostBack" runat="server" Font-Size="8pt" Font-Names="Tahoma" Width="100%"></asp:label></TD>
                </TR>
               
             <% If Label1.Text <> "" Then%>
             <tr>
                 <td align="left" colspan="2" bgcolor="SteelBlue">
                 </td>
             </tr>
            
            
             <tr>
                 <td align="left" class="TDData" colspan="2">
                     <asp:Label ID="Label1" runat="server" CssClass="TDData" ForeColor="Red"></asp:Label></td>
             </tr>
             <% End If%>
            
       </table>
      
    </form>
</body>
</html>

*************************************************************************************************

My VB.net code behind Code is:

Imports System.Configuration
Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Web
Imports System.Web.SessionState
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls
Imports System.Data.SqlClient
imports System.Web.Security
imports System.Text
imports System.IO
Imports System.Reflection
Imports System.Web.UI.AttributeCollection

Partial Class KeyMilestones
    Inherits System.Web.UI.Page
    'Dim FilterImage As HyperLink
    Dim FilterDropDown As DropDownList
    Dim FilterOnOff As String
    Dim ConnectionString As String = "server=S20545702766106;database=Staging;uid=sa;password=boss;"
    Protected Sub CmdFilter_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles CmdFilter.Click
        'Old code in Design
        '   parent.window.history.back();
        Dim i As Integer
        Dim Col_Name As String

        If CmdFilter.Text = "Filter ON" Then

            For i = 1 To GridView1.HeaderRow.Cells.Count - 1
                Col_Name = GridView1.Columns(i).HeaderText()
                'Response.Write(GridView1.Columns(i).HeaderText.Length)
                'Response.Write(GridView1.Columns(i).HeaderText())
                FilterDropDown = New DropDownList
                FilterDropDown.ID = "Filter" & i
                Dim sqlText As String = "select DISTINCT " & Col_Name & " from KeyMilestones Order by " & Col_Name & " DESC"
                FilterDropDown.DataSource = GetDr(sqlText)

                FilterDropDown.DataTextField = Col_Name
                FilterDropDown.DataValueField = Col_Name
                'FilterDropDown.Width = Int(GridView1.Columns(i).HeaderText.Length) * 10
                If Col_Name <> "Product" Then
                    FilterDropDown.Width = 75
                Else
                    FilterDropDown.Width = 85
                End If

                FilterDropDown.DataBind()
                FilterDropDown.CssClass = "selectbox"

                'FilterDropDown.Width = IIf(Col_Name <> "Product", 75, 85)
                GridView1.HeaderRow.Cells(i).Controls.Add(FilterDropDown)
                FilterDropDown.Visible = True

                'FilterImage = New HyperLink
                'FilterImage.ImageUrl = "~/Filter.png"
                'FilterImage.NavigateUrl = "DisplayPR.aspx"
                'FilterImage.NavigateUrl = "javascript:ywindow = window.open ('DisplayPR.aspx','PRDisplay','width=1000,height=600','location=1,status=1,scrollbars=1');parent.window.history.back();"
                'FilterImage.Visible = True
                'FilterImage.Width = "5.0"
                'FilterImage.Height = "8.0"
                ''FilterImage.Style.Add("align", "<BR/>;")
                'FilterImage.ID = "Filter" & i
                'GridView1.HeaderRow.Cells(i).Controls.Add(FilterImage)

            Next
            CmdFilter.Text = "Filter OFF"

        Else
            GridView1.HeaderRow.Cells(i).Controls.Remove(FilterDropDown)
            CmdFilter.Text = "Filter ON"
        End If

    End Sub

    Private Function GetDr(ByVal sqlText As String) As SqlDataReader

        Dim dr As SqlDataReader
        Dim sqlConn As SqlConnection = New SqlConnection("Data Source=S20545702766106;Initial Catalog=Staging;User ID=sa;Password=boss")
        Dim sqlCmd As SqlCommand = New SqlCommand(sqlText, sqlConn)
        sqlCmd.Connection.Open()

        dr = sqlCmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection)
        Return dr

    End Function

    Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click


        ExportExcel("C:\KeyMilestones.xls", GridView1)


        '    private void ExportGridView()

        '{

        '    string attachment = "attachment; filename=Contacts.xls";

        '    Response.ClearContent();

        '    Response.AddHeader("content-disposition", attachment);

        '    Response.ContentType = "application/ms-excel";

        '    StringWriter sw = new StringWriter();

        '    HtmlTextWriter htw = new HtmlTextWriter(sw);

        '    GridView1.RenderControl(htw);

        '    Response.Write(sw.ToString());

        '    Response.End();

        '}
    End Sub


    Public Sub ExportExcel(ByVal filename As String, ByVal gv As GridView)
        Response.ClearContent()
        Response.AddHeader("content-disposition", "attachment; filename=" & filename & ".xls")
        Response.ContentType = "application/vnd.ms-excel"
        Dim sw As New StringWriter()
        Dim htw As New HtmlTextWriter(sw)
        gv.RenderControl(htw)
        Response.Write(sw.ToString())
        Response.[End]()
    End Sub

    'To Overcome the error " Control 'GridView1' of type 'GridView' must be placed inside a form tag with runat=server."
    Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)

    End Sub


    Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles GridView1.PageIndexChanging
        'clean up expanded records.
        Me.txtExpandedDivs.Text = ""
        GridView1.PageIndex = e.NewPageIndex
        BindData()
    End Sub

    Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound

        'If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
        'If your page size is 10, only 10 sub queries will be done.


        If e.Row.RowType = DataControlRowType.DataRow Or e.Row.RowType = ListItemType.AlternatingItem Then

            'Child query
            Dim DetailsQuery As String = "SELECT * from KeyMilestones where [PR] = '" & e.Row.Cells(1).Text & "' "


            'Dim DetailsQuery As String = "SELECT C.CompanyName, OD.UnitPrice, " +
            '   "OD.Quantity,  OD.Discount, E.FirstName, E.LastName " +
            '"FROM [Order Details] as OD, [Customers] as C, " +
            '"[Orders] as O, [Employees] as E " +
            '"where OD.OrderID = O.OrderID and " +
            '"O.CustomerID = C.CustomerID and O.EmployeeID = E.EmployeeID and " +
            '"O.OrderID = '" + e.Item.Cells(1).Text + "' and " +
            '"C.CustomerID = '" + e.Item.Cells(2).Text + "' and " +
            '"E.EmployeeID = '" + e.Item.Cells(3).Text + "'"




            'Here I am grabbing the additional data and putting it into mini datagrids...

            'If you wish to just use labels, or other controls, just bind the data as you

            'wish, and render to html as I did.

            Dim ds As DataSet = Me.RunQuery(DetailsQuery)

            Dim NewDg As New GridView

            NewDg.AutoGenerateColumns = True

            NewDg.Width = Unit.Percentage(100)

            NewDg.DataSource = ds

            NewDg.DataBind()



            SetProps(NewDg)



            Dim sw As New System.IO.StringWriter

            Dim htw As New System.Web.UI.HtmlTextWriter(sw)

            NewDg.RenderControl(htw)

            'Dim DivStart As String = "<DIV id='uniquename" + e.Item.ItemIndex.ToString() + "' style='DISPLAY: none';>"

            Dim DivStart As String = "<DIV id='uniquename" & e.Row.RowIndex.ToString & "' style='DISPLAY: none';>"

            Dim DivBody As String = sw.ToString()

            Dim DivEnd As String = "</DIV>"

            Dim FullDIV As String = DivStart & DivBody & DivEnd



            Dim LastCellPosition As Integer = e.Row.Cells.Count - 1

            Dim NewCellPosition As Integer = e.Row.Cells.Count - 2



            'Dim LastCellPosition As Integer = e.Item.Cells.Count - 1

            'Dim NewCellPosition As Integer = e.Item.Cells.Count - 2




            'e.Item.Cells(0).ID = "CellInfo" + e.Item.ItemIndex.ToString()
            e.Row.Cells(0).ID = "CellInfo" & e.Row.RowIndex.ToString



            'If e.Item.ItemType = ListItemType.Item Then
            If e.Row.RowType = DataControlRowType.DataRow Then

                e.Row.Cells(LastCellPosition).Text() = e.Row.Cells(LastCellPosition).Text & "</td><tr><td bgcolor='f5f5f5'></td><td colspan='" & NewCellPosition.ToString & "'>" & FullDIV


                'e.Item.Cells(LastCellPosition).Text() = e.Item.Cells(LastCellPosition).Text +
                '     "</td><tr><td bgcolor='f5f5f5'></td><td colspan='" +
                'NewCellPosition.ToString(+"'>" + FullDIV)

            Else

                e.Row.Cells(LastCellPosition).Text = e.Row.Cells(LastCellPosition).Text & "</td><tr><td bgcolor='d3d3d3'></td><td colspan='" & NewCellPosition.ToString & "'>" & FullDIV

            End If


            e.Row.Cells(0).Attributes("onclick") = "HideShowPanel('uniquename" & e.Row.RowIndex.ToString & "'); ChangePlusMinusText('" & e.Row.Cells(0).ClientID & "'); SetExpandedDIVInfo('" & _
                e.Row.Cells(0).ClientID & "','" & Me.txtExpandedDivs.ClientID & _
               "', 'uniquename" & e.Row.RowIndex.ToString & "');"


            e.Row.Cells(0).Attributes("onmouseover") = "this.style.cursor='pointer'"

            e.Row.Cells(0).Attributes("onmouseout") = "this.style.cursor='pointer'"


            'e.Item.Cells(0).Attributes("onclick") = "HideShowPanel('uniquename" +
            '   e.Item.ItemIndex.ToString() + "'); ChangePlusMinusText('" +
            '   e.Item.Cells(0).ClientID + "'); SetExpandedDIVInfo('" +
            '   e.Item.Cells(0).ClientID + "','" + Me.txtExpandedDivs.ClientID +
            '   "', 'uniquename" + e.Item.ItemIndex.ToString() + "');"


            'e.Item.Cells(0).Attributes("onmouseover") = "this.style.cursor='pointer'"

            'e.Item.Cells(0).Attributes("onmouseout") = "this.style.cursor='pointer'"

        End If




    End Sub

    Public Sub SetProps(ByVal DG As System.Web.UI.WebControls.GridView)

        '***************************************************

        DG.Font.Size = System.Web.UI.WebControls.FontUnit.Parse("8")

        DG.Font.Bold = False

        DG.Font.Name = "tahoma"



        '*****************Professional 2*******************



        'Border Props

        DG.GridLines = GridLines.Both

        DG.CellPadding = 3

        DG.CellSpacing = 0

        DG.BorderColor = System.Drawing.Color.FromName("#CCCCCC")

        DG.BorderWidth = System.Web.UI.WebControls.Unit.Pixel(1)





        'Header Props

        DG.HeaderStyle.BackColor = System.Drawing.Color.SteelBlue

        DG.HeaderStyle.ForeColor = System.Drawing.Color.White

        DG.HeaderStyle.Font.Bold = True

        DG.HeaderStyle.Font.Size = System.Web.UI.WebControls.FontUnit.Parse("8")

        DG.HeaderStyle.Font.Name = "tahoma"


        DG.RowStyle.BackColor = Color.LightSteelBlue
        '        DG.ItemStyle.BackColor = System.Drawing.Color.LightSteelBlue



    End Sub

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        'If Not IsPostBack Then
        Dim myHTMLLink As New HtmlLink
        myHTMLLink.Href = "~/Styles/Dashboard.css"
        myHTMLLink.Attributes.Add("rel", "stylesheet")
        myHTMLLink.Attributes.Add("type", "text/css")
        Page.Header.Controls.Add(myHTMLLink)


        Dim js As New HtmlGenericControl("script")
        js.Attributes("Type") = "text/javascript"
        js.Attributes("src") = "dropdown_menu.js"
        Page.Header.Controls.Add(js)
        Me.LabelPostBack.Text = ""
        'ClientScript.RegisterClientScriptInclude("script", "dropdown_menu_hack.js")

        '        End If



        If Not Page.IsPostBack Then
            'Bind Master Details
            BindData()
        Else
            For i As Integer = 0 To Me.GridView1.Columns.Count - 1
                'After Postback ID's get lost. Javascript will not work without it,
                'so we must set them back.
                'Me.GridView1.Columns(i).Cells(0).ID = "CellInfo" + i.ToString()
                'Me.GridView1.Rows(i).Cells(0).ID = "CellInfo" + i.ToString()
                Me.GridView1.SelectedRow.Cells(0).ID = "CellInfo" + i.ToString()

            Next

            'If it is a postback that is not from the grid, we have to expand the rows
            'the user had expanded before. We have to check first who called this postback
            'by checking the Event Target. The reason we check this, is because we don't need
            'to expand if it is changing the page of the datagrid, or sorting, etc...
            If Request("__EVENTTARGET") Is Nothing Then
                Return
            Else
                Dim strEventTarget As String = Request("__EVENTTARGET").ToString().ToLower()

                'GridView1 is the name of the grid. If you modify the grid name,
                'make sure to modify this if statement.
                If strEventTarget.IndexOf("GridView1") = -1 Then
                    If Not Page.IsStartupScriptRegistered("ShowDataJS") Then
                        Page.RegisterStartupScript("ShowDataJS", "<script>ShowExpandedDivInfo('" & Me.txtExpandedDivs.ClientID & "','" & Me.GridView1.ClientID & "');</script>")

                    End If
                End If

            End If
        End If

    End Sub

#Region "Database Methods"

    Private Sub BindData()

        '==========Query For Master Rows==================

        Dim QueryString As String = "SELECT * FROM KeyMilestones_Master"


        If ViewState("sortby") Is Nothing Then

            QueryString = QueryString & " "

        Else

            QueryString = QueryString & " order by " & ViewState("sortby").ToString()

        End If

        '=================================================



        Dim conn As New System.Data.SqlClient.SqlConnection

        Try

            conn.ConnectionString = ConnectionString

            If conn.State = System.Data.ConnectionState.Closed Then

                conn.Open()

            End If



            Dim adapter As New System.Data.SqlClient.SqlDataAdapter(QueryString, conn)

            Dim ds As New DataSet

            adapter.Fill(ds)

            GridView1.DataSource = ds



            GridView1.DataBind()

        Catch ex1 As Exception

            Response.Write("An error has occurred: ")

            Response.Write(ex1.Message.ToString())

            Response.End()

        Finally

            If conn.State = System.Data.ConnectionState.Open Then

                conn.Close()

            End If

        End Try

    End Sub



    Private Function RunQuery(ByVal QueryString As String) As DataSet
        Dim conn As New System.Data.SqlClient.SqlConnection

        Try
            conn.ConnectionString = ConnectionString
            If conn.State = System.Data.ConnectionState.Closed Then
                conn.Open()
            End If

            Dim adapter As New System.Data.SqlClient.SqlDataAdapter(QueryString, conn)
            Dim ds As New DataSet
            adapter.Fill(ds)
            Return ds
        Catch ex1 As Exception
            Response.Write("An Error has occurred.<BR />")
            Response.Write(ex1.Message.ToString())
            Response.[End]()
            'This line below will never execute.
            Return Nothing
        Finally
            If conn.State = System.Data.ConnectionState.Open Then
                conn.Close()
            End If
        End Try
    End Function
#End Region

#Region "GridViewMethods"
   
    Public Sub SetProps(ByVal DG As System.Web.UI.WebControls.DataGrid)
        '**************************************************************************
        DG.Font.Size = System.Web.UI.WebControls.FontUnit.Parse("8")
        DG.Font.Bold = False
        DG.Font.Name = "tahoma"

        '******************************Professional 2*********************************

        'Border Props
        DG.GridLines = GridLines.Both
        DG.CellPadding = 3
        DG.CellSpacing = 0
        DG.BorderColor = System.Drawing.Color.FromName("#CCCCCC")
        DG.BorderWidth = System.Web.UI.WebControls.Unit.Pixel(1)


        'Header Props
        DG.HeaderStyle.BackColor = System.Drawing.Color.SteelBlue
        DG.HeaderStyle.ForeColor = System.Drawing.Color.White
        DG.HeaderStyle.Font.Bold = True
        DG.HeaderStyle.Font.Size = System.Web.UI.WebControls.FontUnit.Parse("8")
        DG.HeaderStyle.Font.Name = "tahoma"

        DG.ItemStyle.BackColor = System.Drawing.Color.LightSteelBlue

    End Sub
#End Region

    Protected Sub GridView1_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles GridView1.Sorting
        Me.txtExpandedDivs.Text = ""
        Dim sortby As String = "[" & e.SortExpression & "]"

        If ViewState("sortby") Is Nothing Then
            sortby = sortby & " ASC"
            ViewState("sortby") = sortby
            BindData()
        Else
            If ViewState("sortby").ToString() = sortby & " ASC" Then
                sortby = sortby & " DESC"
                ViewState("sortby") = sortby
                BindData()
            ElseIf ViewState("sortby").ToString() = sortby & " DESC" Then
                sortby = sortby & " ASC"
                ViewState("sortby") = sortby
                BindData()
            Else
                sortby = sortby & " ASC"
                ViewState("sortby") = sortby
                BindData()
            End If
        End If
    End Sub
End Class


Please help me to resolve this issue,

regards
Surendra
Posted on:
4/27/2009 12:00:00 AM
Posted by:
Pit
Thank you so much. do you also have a link for GridView using VB. :-)
Posted on:
4/23/2009 12:00:00 AM
Posted by:
Pit
Hi,

can you write it in VB? :-)

Thanks a lot.
Posted on:
4/9/2009 12:00:00 AM
Posted by:
I''m having some trouble with this, it works, but I get some strange results.  I have a master gridview with 6 columns, 2 of which are hidden.

1 - +/-
2 - Key1 (Visible = false in RowCreated)
3 - Key2 (Visible = false in RowCreated)
4 - Buttons (Edit/Update, Cancel)
5 - Text1
6 - Text2

When the child datagrid is generated the Text2 field is appended to the end of the inserted code, rather than at the front where the code puts it.

                GridView NewDg = new GridView();
                NewDg.AutoGenerateColumns = true;
                NewDg.Width = Unit.Percentage(100.00);
                NewDg.Font.Size = 8;
                NewDg.Font.Name = "Tahoma";
                NewDg.HeaderStyle.HorizontalAlign = HorizontalAlign.Left;
                NewDg.BorderColor = System.Drawing.Color.Black;
                NewDg.DataSource = EquipChildren.Tables[0];
                NewDg.DataBind();
                System.IO.StringWriter sw = new System.IO.StringWriter();
                System.Web.UI.HtmlTextWriter htw = new System.Web.UI.HtmlTextWriter(sw);
                NewDg.RenderControl(htw);
                string bg = "white";
                if (e.Row.RowIndex % 2 == 0)
                {
                    bg = "#EFF3FB";
                }
                else
                {
                    bg = "white";
                }
                string DivStart = "<DIV id=''uniquename" + e.Row.RowIndex.ToString() + "'' style=''DISPLAY: none; background-color: " + bg + ";''>";
                string DivBody = sw.ToString();
                string DivEnd = "</DIV>";
                string FullDIV = DivStart + DivBody + DivEnd;
                int LastCellPosition = e.Row.Cells.Count - 2;
                int NewCellPosition = e.Row.Cells.Count - 3;
                e.Row.Cells[0].ID = "CellInfo" + e.Row.RowIndex.ToString();
                //Match color of div which we will expand base on row
                if (e.Row.RowIndex % 2 == 0)
                {
                    //set to regular row style
                    e.Row.Cells[LastCellPosition].Text = e.Row.Cells[LastCellPosition].Text + "</td></tr>\n<tr><td bgcolor=''#EFF3FB''></td><td colspan=''" + NewCellPosition + "''>" + FullDIV;
                }
                else
                {
                    //set to alternative row style
                    e.Row.Cells[LastCellPosition].Text = e.Row.Cells[LastCellPosition].Text + "</td></tr>\n<tr><td bgcolor=''white''></td><td colspan=''" + NewCellPosition + "''>" + FullDIV;
                }
                if (EquipChildren == null || EquipChildren.Tables.Count == 0 || EquipChildren.Tables[0].Rows.Count == 0)
                {
                    e.Row.Cells[0].Text = "";
                }
                else
                {
                    e.Row.Cells[0].Attributes["onclick"] = "HideShowPanel(''uniquename" +
                       e.Row.RowIndex.ToString() + "''); ChangePlusMinusText(''" +
                       e.Row.Cells[0].ClientID + "''); SetExpandedDIVInfo(''" +
                       e.Row.Cells[0].ClientID + "'',''" + this.txtExpandedDivs.ClientID +
                       "'', ''uniquename" + e.Row.RowIndex.ToString() + "'');";
                    e.Row.Cells[0].Attributes["onmouseover"] = "this.style.cursor=''pointer''";
                    e.Row.Cells[0].Attributes["onmouseout"] = "this.style.cursor=''pointer''";
                }

I''ve tried every combination of LastCellPosition and NewCellPosition that I can think of. Any help would be greatly appreciated.
Posted on:
3/9/2009 12:00:00 AM
Posted by:
Jim
os_os,   This is a server control that already does everything for you:
http://www.DigitalTools.com/GVT.aspx
Posted on:
3/7/2009 12:00:00 AM
Posted by:

dear all;

   can anyone help me in my issue... i want the same example but with user control already created and to be registered ..instead of dynamically table to display the date...(user control can have assume 2 text boxes that hold the data from the database according the clicked row

pls pls any link or example or at least suggestions..
thanks in advance
 

Posted on:
3/5/2009 12:00:00 AM
Posted by:

dear all;

   can anyone help me in my issue... i want the same example but with user control already created and to be registered ..instead of dynamically table to display the date...(user control can have assume 2 text boxes that hold the data from the database according the clicked row

pls pls any link or example or at least suggestions..
thanks in advance
 

Posted on:
1/30/2009 12:00:00 AM
Posted by:
Hi Rajib

I have successfully added this into my project but have found that I can no longer use Eval in my ItemTemplates. Do you have any idea why this is?

Regards

Posted on:
1/15/2009 12:00:00 AM
Posted by:
Hi Rajib,

I need something suchlike yours but the detail rows should be seen on same master grid as new rows under the master row which is clicked.
the collapsing action should happen on the same one grid.

Is it possible with your structure ?
Posted on:
1/15/2009 12:00:00 AM
Posted by:

Of course the master row and details rows has same columns.
The purpose is first row will presenet realization of a account for 12 months and the detail rows will show the budgets for that account. like that;

         Account        Jan       Feb      March   Apr      May     June      July      Aug     Sept     Oct      Nov      Dec
[-]   ASD-75-49   45.75      4.12     10 .10  11.11   12.12      13.13   14.14     15.15   16.16   17.17   18.18   19.19
                             101.45        0      14.10      0         0                 0          0           0         0          0           0         0


Posted on:
1/15/2009 12:00:00 AM
Posted by:

This should be easily done with the existing code.  Bind the parent rows with your query to obtain the desired parent rows.  Modify the RowDataBound method to get the child grid based on the your child query.  Next just modify the child grid properties not to display the header.  This should give you the output you want.  Let me know if this worked for you.

Rajib

Posted on:
1/15/2009 12:00:00 AM
Posted by:

sorry for writing as a new post..

Posted on:
1/15/2009 12:00:00 AM
Posted by:
Hi Rajib,

If i use second gridview i can not align both gridview''s columns purely.  for example, january data for main row and child data for Jan. should be one under the other.
If i fill details data to second gridview, the months aligning goes wrong.

That''s way i asked for using one grid.
any idea will be appreciated..
Posted on:
1/14/2009 12:00:00 AM
Posted by:

Hello,

When I enable paging on the child grid view, I get a NullReferenceException at NewDg.DataBind(). This happens when the page size on the child grid view is less than the number of data rows returned by the data source. Any ideas how to resolve this issue.?

TIA
Arshad

Posted on:
1/6/2009 12:00:00 AM
Posted by:
Hi,
I have a query that how this can be done in c#.NET win forms

regards
Gaurav
Posted on:
1/15/2009 12:00:00 AM
Posted by:
I think this is available in windows forms, but wasn't out of the box for the web.  That was the reason to create this.
Posted on:
12/22/2008 12:00:00 AM
Posted by:
I actualy ended up making a work around which I think works better for my project which is a IF statement in the rowdatabound event off of a radio button list I have on the page giving the user the option to expand all or close. The reason I did this was that i am also allowing the user to change the size of the page, search from several different ways and thous all caused a post back so that seemed to go with the flow of everything else.

But one thing I did mess with and got to work was I created a third GridView within the second that you have shown in your code here. So basicaly I have the Parent GridView, the Dynamic Child (both pritty close to the code examples you have given), and then a third Dynamic Child of the Child. If thats not to confusing hehe. Basicaly I created an RowDataBound event for the first child from there I created the third, I think the tricky thing was basicaly you have to take another step uniquely identifiing the third grid with consideration that you may have several of thous child grids on the page.

It works really well, the only thing I am having trouble with now is getting the image on the third grid to change on click, other then that works like a charm.
Posted on:
12/15/2008 12:00:00 AM
Posted by:
I tried this but I must be missing something along the way. I set the field in the gridview as such

<asp:HyperLinkField Text="<img src=''27.png''>" />

Then adjusted the javascript like so, leaving your code commented out so you have a visual refference on which graphics I was using for + -:

function getElement(aID)

{

return (document.getElementById) ? document.getElementById(aID) : getElement[aID];

}

//This method will switch the plus to a minus and vice versa on the client side

function ChangePlusMinusText(PlusMinusCellID)

{

try

{

var PlusMinusCellObj = getElement(PlusMinusCellID);

if ( PlusMinusCellObj != null )

{

//if ( PlusMinusCellObj.innerHTML == "<A>[+]</A>")

if ( PlusMinusCellObj.innerHTML == "<img src=''27.png''>")

{

//PlusMinusCellObj.innerHTML = "<A>[-]</A>";

PlusMinusCellObj.innerHTML = "<img src=''26.png''>";

}

else

{

//PlusMinusCellObj.innerHTML = "<A>[+]</A>";

PlusMinusCellObj.innerHTML = "<img src=''27.png''>";

}

}

}

catch(e)

{

alert( "Error in ChangePlusMinusText Method: " + e);

}

}

//After a postback occurs, this method will re-expand old data.

function ShowExpandedDivInfo(TextBoxIDOfExpandedDiv, DataGridID)

{

try

{

var DIVTB = getElement(TextBoxIDOfExpandedDiv);

if ( DIVTB != null )

{

var data = DIVTB.value;

if ( data != null && data.length > 0 && data != ",")

{

var SplitData = data.split(",");

//Temp variables

var SplitDataOfArrayItem = "";

var DivIdentifier = "";

var PlusMinusCellIdentifier = "";

for ( var i = 0; i < SplitData.length; i++)

{

//Format of textbox data

//NameOfDIV + "@" + PlusMinusCellID

SplitDataOfArrayItem = SplitData[i].split("@");

//Get the ID of the DIV section

DivIdentifier = SplitDataOfArrayItem[0];

//Get the ID of the Cell with the Plus or Minus showing collapsed or expanded state.

PlusMinusCellIdentifier = SplitDataOfArrayItem[1];

if ( DivIdentifier != null && DivIdentifier.length > 0 )

{

//Expand DIV Section

ShowPanel( DivIdentifier );

}

if ( PlusMinusCellIdentifier != null && PlusMinusCellIdentifier.length > 0 )

{

var PlusMinusCellObj = getElement(PlusMinusCellIdentifier);

if ( PlusMinusCellObj != null )

{

//We found the cell to expand

//PlusMinusCellObj.innerHTML = "<A>[-]</A>";

PlusMinusCellObj.innerHTML = "<img src=''26.png''>";

}

else

{

//We DID NOT FIND the cell to expand

//May Have Been Lost After Postback.

//Invoke Method to get id of cell using partial data which will always

//be unique...

var NewPlusMinusCellObjID = getItem(PlusMinusCellIdentifier, DataGridID);

if ( NewPlusMinusCellObjID != null )

{

var NewCellObject = getElement(NewPlusMinusCellObjID);

if ( NewCellObject != null )

{

var rows = NewCellObject.getElementsByTagName("td");

if ( rows != null && rows.length >= 0)

{

//the initial row has to be set to expanded....

try

{

//rows[0].innerHTML = "<A>[-]</A>";

rows[0].innerHTML = "<img src=''26.png''>";

}

catch(e)

{

//alert("Error in setting row to expanded in ShowExpandedDivInfo Method. Error 101: " + e);

}

}//end of rows if statement

}//end of NewCellObject != null

}//end of NewPlusMinusCellObjID != null

}//end of PlusMinusCellObj != null if else

}//end of PlusMinusCellIdentifier != null

}//end of for loop

}

}

}

catch(e)

{

alert( "Error in ShowExpandedDivInfo Method: " + e);

}

}

//This will keep the data in the hidden textbox field.

function SetExpandedDIVInfo(PlusMinusCellID, HiddenTextBoxToHoldDivInfo, DIVInfoID)

{

try

{

var IsExpanded = false;

var HTBObj = getElement(HiddenTextBoxToHoldDivInfo);

var HLObj = getElement(PlusMinusCellID);

if ( HLObj != null && HTBObj != null)

{

//if ( HLObj.innerHTML == "<A>[+]</A>")

if ( HLObj.innerHTML == "<img src=''27.png''>")

{

IsExpanded = false;

}

else

{

IsExpanded = true;

}

//What is in the hidden DIV Textbox field?

var ExpandedData = HTBObj.value;

if ( ExpandedData == null || ExpandedData == "," )

{

ExpandedData = "";

}

//===============================================================

if ( ExpandedData.length < 1 && IsExpanded == true )

{

//No Previous Expanded Data.

//Add new Expanded Field.

ExpandedData = DIVInfoID + "@" + PlusMinusCellID;

HTBObj.value = ExpandedData;

}

else if ( ExpandedData.length < 1 && IsExpanded == false )

{

//No Previous Expanded Data.

//Clean up old Expanded Field.

//ExpandedData is empty, so no work is needed.

}

else if ( ExpandedData.length > 0 && ExpandedData.indexOf(DIVInfoID) == -1 && IsExpanded == true )

{

//Expanded data has data from before.

//No existing record exists for this field.

//We can add new Expanded field.

//We can use a comma as a delimeter.

ExpandedData = ExpandedData + "," + DIVInfoID + "@" + PlusMinusCellID;

ExpandedData = ExpandedData.replace( ",," , ",");

HTBObj.value = ExpandedData;

}

else if ( ExpandedData.indexOf(DIVInfoID) > -1 && IsExpanded == true )

{

//Expanded data has data from before.

//Existing record exists for this field.

//We do not need to perform any updates.

}

else if ( ExpandedData.indexOf(DIVInfoID) > -1 && IsExpanded == false )

{

//Expanded data has data from before.

//Existing record exists for this field

//We remove it as it is not expanded any longer.

ExpandedData = ExpandedData.replace(DIVInfoID + "@" + PlusMinusCellID ,"");

//Make sure we don''t have a double delimeter

ExpandedData = ExpandedData.replace( ",," , ",");

HTBObj.value = ExpandedData;

}

else if ( ExpandedData.indexOf(DIVInfoID) == -1 && IsExpanded == false )

{

//Expanded data has data from before.

//Existing record does not exists for this field

//No work is needed.

}

//Recheck we don''t have any garbage data.

//Added because deleting items, causes a comma

//to stay sometimes.

if ( HTBObj != null && HTBObj.value == "," )

{

HTBObj.value = "";

}

//===============================================================

}

}

catch(e)

{

alert( "Error in SetExpandedDIVInfo Method: " + e);

}

}

//This method will hide the panel.

function HidePanel(Panel)

{

try

{

var ChosenPanel = getElement(Panel);

if ( ChosenPanel != null )

{

getElement(Panel).style.display = "none";

}

}

catch(e)

{

alert( "Error in HidePanel Method: " + e);

}

}

//This method will show the panel.

function ShowPanel(Panel)

{

try

{

var ChosenPanel = getElement(Panel);

if ( ChosenPanel != null )

{

getElement(Panel).style.display = "block";

}

}

catch(e)

{

alert( "Error in ShowPanel Method: " + e);

}

}

//This method will hide and show the panel.

function HideShowPanel(Panel)

{

try

{

var ChosenPanel = getElement(Panel);

if ( ChosenPanel != null )

{

var currentdisplay = getElement(Panel).style.display;

if ( currentdisplay != "block")

{

getElement(Panel).style.display = "block";

}

else

{

getElement(Panel).style.display = "none";

}

}

}

catch(e)

{

alert( "Error in HideShowPanel Method: " + e);

}

}

//This method will get the object using partial id match.

function getItem(IDSearchCriteria, DataGridID)

{

try

{

if ( IDSearchCriteria == null || IDSearchCriteria.length <= 0 )

{

return null;

}

else if ( DataGridID == null || DataGridID.length <= 0 )

{

return null;

}

if( document.getElementsByTagName )

{

var table = document.getElementById(DataGridID);

if ( table != null )

{

var rows = table.getElementsByTagName("tr");

for ( var i = 0; i < rows.length; i++ )

{

var Identity = rows[i].id;

if ( Identity != null && Identity.length > 0 )

{

var cellid = IDSearchCriteria.substring( IDSearchCriteria.lastIndexOf("_") + 1 );

if ( Identity.match(cellid) )

{

//alert("Found: " + Identity);

return Identity;

}

}

}

}

return null;

}

else

{

return null;

}

}

catch(e)

{

alert( "Error in getItem Method: " + e);

return null;

}

}

The problem then is that it doesnt switch images, the rows expand as they should but the graphic does not change. At first I thought maybe it was a issue were the second graphic was not loaded on the screen so therefor there for nothing to show. So I started with both images in the tag then setting the + image as the one to be display in this procedure:

protected void GridView3_RowCreated(object sender, GridViewRowEventArgs e)

{

//Hide ID columns from user

if (e.Row.RowType == DataControlRowType.Header || e.Row.RowType == DataControlRowType.DataRow)

{

e.Row.Cells[1].Visible = false;

e.Row.Cells[0].Text = "<img src=''27.png''>";

}

}

That doesnt work either, it works for the first click then no changes, which tells me I have something wrong with the javascript side of it all. So kind of lost on were to go now.

Thanks in Advance for your help.

Posted on:
12/15/2008 12:00:00 AM
Posted by:
In the ChangePlusMinsText(PlusMinusCellID) function, put an alert( PlusMinusCellObj.innerHTML ); and let me know what you get.
Posted on:
12/15/2008 12:00:00 AM
Posted by:
I tried this but I must be missing something along the way. I set the field in the gridview as such

<asp:HyperLinkField Text="<img src=''27.png''>" />

Then adjusted the javascript like so, leaving your code commented out so you have a visual refference on which graphics I was using for + -:

function getElement(aID)

{

return (document.getElementById) ? document.getElementById(aID) : getElement[aID];

}

//This method will switch the plus to a minus and vice versa on the client side

function ChangePlusMinusText(PlusMinusCellID)

{

try

{

var PlusMinusCellObj = getElement(PlusMinusCellID);

if ( PlusMinusCellObj != null )

{

//if ( PlusMinusCellObj.innerHTML == "<A>[+]</A>")

if ( PlusMinusCellObj.innerHTML == "<img src=''27.png''>")

{

//PlusMinusCellObj.innerHTML = "<A>[-]</A>";

PlusMinusCellObj.innerHTML = "<img src=''26.png''>";

}

else

{

//PlusMinusCellObj.innerHTML = "<A>[+]</A>";

PlusMinusCellObj.innerHTML = "<img src=''27.png''>";

}

}

}

catch(e)

{

alert( "Error in ChangePlusMinusText Method: " + e);

}

}

//After a postback occurs, this method will re-expand old data.

function ShowExpandedDivInfo(TextBoxIDOfExpandedDiv, DataGridID)

{

try

{

var DIVTB = getElement(TextBoxIDOfExpandedDiv);

if ( DIVTB != null )

{

var data = DIVTB.value;

if ( data != null && data.length > 0 && data != ",")

{

var SplitData = data.split(",");

//Temp variables

var SplitDataOfArrayItem = "";

var DivIdentifier = "";

var PlusMinusCellIdentifier = "";

for ( var i = 0; i < SplitData.length; i++)

{

//Format of textbox data

//NameOfDIV + "@" + PlusMinusCellID

SplitDataOfArrayItem = SplitData[i].split("@");

//Get the ID of the DIV section

DivIdentifier = SplitDataOfArrayItem[0];

//Get the ID of the Cell with the Plus or Minus showing collapsed or expanded state.

PlusMinusCellIdentifier = SplitDataOfArrayItem[1];

if ( DivIdentifier != null && DivIdentifier.length > 0 )

{

//Expand DIV Section

ShowPanel( DivIdentifier );

}

if ( PlusMinusCellIdentifier != null && PlusMinusCellIdentifier.length > 0 )

{

var PlusMinusCellObj = getElement(PlusMinusCellIdentifier);

if ( PlusMinusCellObj != null )

{

//We found the cell to expand

//PlusMinusCellObj.innerHTML = "<A>[-]</A>";

PlusMinusCellObj.innerHTML = "<img src=''26.png''>";

}

else

{

//We DID NOT FIND the cell to expand

//May Have Been Lost After Postback.

//Invoke Method to get id of cell using partial data which will always

//be unique...

var NewPlusMinusCellObjID = getItem(PlusMinusCellIdentifier, DataGridID);

if ( NewPlusMinusCellObjID != null )

{

var NewCellObject = getElement(NewPlusMinusCellObjID);

if ( NewCellObject != null )

{

var rows = NewCellObject.getElementsByTagName("td");

if ( rows != null && rows.length >= 0)

{

//the initial row has to be set to expanded....

try

{

//rows[0].innerHTML = "<A>[-]</A>";

rows[0].innerHTML = "<img src=''26.png''>";

}

catch(e)

{

//alert("Error in setting row to expanded in ShowExpandedDivInfo Method. Error 101: " + e);

}

}//end of rows if statement

}//end of NewCellObject != null

}//end of NewPlusMinusCellObjID != null

}//end of PlusMinusCellObj != null if else

}//end of PlusMinusCellIdentifier != null

}//end of for loop

}

}

}

catch(e)

{

alert( "Error in ShowExpandedDivInfo Method: " + e);

}

}

//This will keep the data in the hidden textbox field.

function SetExpandedDIVInfo(PlusMinusCellID, HiddenTextBoxToHoldDivInfo, DIVInfoID)

{

try

{

var IsExpanded = false;

var HTBObj = getElement(HiddenTextBoxToHoldDivInfo);

var HLObj = getElement(PlusMinusCellID);

if ( HLObj != null && HTBObj != null)

{

//if ( HLObj.innerHTML == "<A>[+]</A>")

if ( HLObj.innerHTML == "<img src=''27.png''>")

{

IsExpanded = false;

}

else

{

IsExpanded = true;

}

//What is in the hidden DIV Textbox field?

var ExpandedData = HTBObj.value;

if ( ExpandedData == null || ExpandedData == "," )

{

ExpandedData = "";

}

//===============================================================

if ( ExpandedData.length < 1 && IsExpanded == true )

{

//No Previous Expanded Data.

//Add new Expanded Field.

ExpandedData = DIVInfoID + "@" + PlusMinusCellID;

HTBObj.value = ExpandedData;

}

else if ( ExpandedData.length < 1 && IsExpanded == false )

{

//No Previous Expanded Data.

//Clean up old Expanded Field.

//ExpandedData is empty, so no work is needed.

}

else if ( ExpandedData.length > 0 && ExpandedData.indexOf(DIVInfoID) == -1 && IsExpanded == true )

{

//Expanded data has data from before.

//No existing record exists for this field.

//We can add new Expanded field.

//We can use a comma as a delimeter.

ExpandedData = ExpandedData + "," + DIVInfoID + "@" + PlusMinusCellID;

ExpandedData = ExpandedData.replace( ",," , ",");

HTBObj.value = ExpandedData;

}

else if ( ExpandedData.indexOf(DIVInfoID) > -1 && IsExpanded == true )

{

//Expanded data has data from before.

//Existing record exists for this field.

//We do not need to perform any updates.

}

else if ( ExpandedData.indexOf(DIVInfoID) > -1 && IsExpanded == false )

{

//Expanded data has data from before.

//Existing record exists for this field

//We remove it as it is not expanded any longer.

ExpandedData = ExpandedData.replace(DIVInfoID + "@" + PlusMinusCellID ,"");

//Make sure we don''t have a double delimeter

ExpandedData = ExpandedData.replace( ",," , ",");

HTBObj.value = ExpandedData;

}

else if ( ExpandedData.indexOf(DIVInfoID) == -1 && IsExpanded == false )

{

//Expanded data has data from before.

//Existing record does not exists for this field

//No work is needed.

}

//Recheck we don''t have any garbage data.

//Added because deleting items, causes a comma

//to stay sometimes.

if ( HTBObj != null && HTBObj.value == "," )

{

HTBObj.value = "";

}

//===============================================================

}

}

catch(e)

{

alert( "Error in SetExpandedDIVInfo Method: " + e);

}

}

//This method will hide the panel.

function HidePanel(Panel)

{

try

{

var ChosenPanel = getElement(Panel);

if ( ChosenPanel != null )

{

getElement(Panel).style.display = "none";

}

}

catch(e)

{

alert( "Error in HidePanel Method: " + e);

}

}

//This method will show the panel.

function ShowPanel(Panel)

{

try

{

var ChosenPanel = getElement(Panel);

if ( ChosenPanel != null )

{

getElement(Panel).style.display = "block";

}

}

catch(e)

{

alert( "Error in ShowPanel Method: " + e);

}

}

//This method will hide and show the panel.

function HideShowPanel(Panel)

{

try

{

var ChosenPanel = getElement(Panel);

if ( ChosenPanel != null )

{

var currentdisplay = getElement(Panel).style.display;

if ( currentdisplay != "block")

{

getElement(Panel).style.display = "block";

}

else

{

getElement(Panel).style.display = "none";

}

}

}

catch(e)

{

alert( "Error in HideShowPanel Method: " + e);

}

}

//This method will get the object using partial id match.

function getItem(IDSearchCriteria, DataGridID)

{

try

{

if ( IDSearchCriteria == null || IDSearchCriteria.length <= 0 )

{

return null;

}

else if ( DataGridID == null || DataGridID.length <= 0 )

{

return null;

}

if( document.getElementsByTagName )

{

var table = document.getElementById(DataGridID);

if ( table != null )

{

var rows = table.getElementsByTagName("tr");

for ( var i = 0; i < rows.length; i++ )

{

var Identity = rows[i].id;

if ( Identity != null && Identity.length > 0 )

{

var cellid = IDSearchCriteria.substring( IDSearchCriteria.lastIndexOf("_") + 1 );

if ( Identity.match(cellid) )

{

//alert("Found: " + Identity);

return Identity;

}

}

}

}

return null;

}

else

{

return null;

}

}

catch(e)

{

alert( "Error in getItem Method: " + e);

return null;

}

}

The problem then is that it doesnt switch images, the rows expand as they should but the graphic does not change. At first I thought maybe it was a issue were the second graphic was not loaded on the screen so therefor there for nothing to show. So I started with both images in the tag then setting the + image as the one to be display in this procedure:

protected void GridView3_RowCreated(object sender, GridViewRowEventArgs e)

{

//Hide ID columns from user

if (e.Row.RowType == DataControlRowType.Header || e.Row.RowType == DataControlRowType.DataRow)

{

e.Row.Cells[1].Visible = false;

e.Row.Cells[0].Text = "<img src=''27.png''>";

}

}

That doesnt work either, it works for the first click then no changes, which tells me I have something wrong with the javascript side of it all. So kind of lost on were to go now.

Thanks in Advance for your help.

Posted on:
12/15/2008 12:00:00 AM
Posted by:

<A><IMG src=”http://localhost:3125/ExpandingGrid/27.png”></A>

Sorry for the double post seems we were both posting at the same time or something.

Posted on:
12/15/2008 12:00:00 AM
Posted by:

<A><IMG src=”http://localhost:3125/ExpandingGrid/27.png”></A>

Sorry for the double post seems we were both posting at the same time or something.

Posted on:
12/15/2008 12:00:00 AM
Posted by:
ahah!  Then, the if statement is failing.  Your syntax has
if ( PlusMinusCellObj.innerHTML == "<img src=''27.png''>") which never maches.  Modify this with what you wrote above, and you should be on you way:

if ( PlusMinusCellObj.innerHTML == "<A><IMG src=”http://localhost:3125/ExpandingGrid/27.png”></A>")

Be careful of the double quotes.  You can also do an index of

if ( PlusMinusCellObj.innerHTML.indexOf("27.png") > -1)
{
     //found the 27.png image
}
Posted on:
12/15/2008 12:00:00 AM
Posted by:
Actualy the message was <IMG src=”http://localhost:3125/ExpandingGrid/27.png”> Sorry about that i was trying something else when I posted the first time
Posted on:
12/15/2008 12:00:00 AM
Posted by:
See the message above.
Posted on:
12/15/2008 12:00:00 AM
Posted by:
Changing the script to:

if ( PlusMinusCellObj.innerHTML.indexOf("27.png") > -1)

{

Works like a charm, thanks a ton Rajib, I realy appreciate it, and sorry for all the double posts lol, seems thats occuring when you have multiple sessions of this page open prior to submitting the comments.

Posted on:
12/15/2008 12:00:00 AM
Posted by:
For whatever reason I cant seem to get expand/close all to work. I tryed it with a hyperlink that dident work then I tryed it with a button, this worked if I threw an alert in the javascript function but as soon as you clicked ok on the alert postback occurs and its collapsed again. The close all doesnt work at all. Can you please provide an example of this.
Posted on:
12/22/2008 12:00:00 AM
Posted by:

How did you tyr to implement this?  If you use a function like this one where divid = uniquename, what happens?

function HideShowAll(divid)
{
    try
    {
        var j = 0;
        for( j = 0; j < 10; j++)
        {
            var dataid = divid + j;
            HideShowPanel(dataid);
        }
    }
    catch(e)
    {}
}

Posted on:
12/12/2008 12:00:00 AM
Posted by:

This is great and really the best example I have seen yet, was very easy to implement with few changes. Really the only thing I changed was that I store my data from my query in a Session DataView variable so that I dont need to requery everytime the user selects sort or paging. With the amount of information needed to be queried by my page this seems to work alot better performance wise.

Can you post a "Expand All" example please, I tryed the example someone posted about but it seems to be set up so that you have to use a hyperlink for every record you are displaying, and thats not going to work for my project. I also tryed to tied it to a single hyperlink on the page and couldent get it to work. I have limited javascript knowledge so im sure thats the problem, but if you could give an example I would appreciate it. Thanks in advance.

Posted on:
12/15/2008 12:00:00 AM
Posted by:

I think the javascript function would be:

function HideShowAll(divid)
{
    try
    {
        var j = 0;
        for( j = 0; j < 10; j++)
        {
            var dataid = divid + j;
            HideShowPanel(dataid);
        }
    }
    catch(e)
    {}
}


You would need to pass the generic div id which is uniquename, HideShowAll('uniquename');
Just view the source of your aspx page using mozilla or ie, and check what your div id's are. It will be something like
uniquename1, uniquename2, etc...



Posted on:
12/12/2008 12:00:00 AM
Posted by:

I was also wondering how hard it would be to adjust the script so that you can use two different graphics insted of the + and -

Posted on:
12/15/2008 12:00:00 AM
Posted by:
you can use images instead of the [+], [-].  Just make sure you modify the ChangePlusMinusText() javascript function to modify the <img> image paths.  currently it changes the plus to a minus.
Posted on:
10/16/2008 12:00:00 AM
Posted by:
Very nice example and source code.  I was able to adapt this very easily, however when my child gridview displays it displays entirely in the width of the first column.  The screenshots above in your article show the child gridview spanning the entire width of the parent columns.  I am having difficulty locating where to adjust this property so the child will span the width of the parent gridview.  Thanks. Marc
Posted on:
10/16/2008 12:00:00 AM
Posted by:
Very nice example and source code.  I was able to adapt this very easily, however when my child gridview displays it displays entirely in the width of the first column.  The screenshots above in your article show the child gridview spanning the entire width of the parent columns.  I am having difficulty locating where to adjust this property so the child will span the width of the parent gridview.  Thanks. Marc
Posted on:
10/17/2008 12:00:00 AM
Posted by:
Check in the datagrid databound method. Here I am building a div, you can set the div width and height as desired.  Let me know if you have trouble finding it.  The example provided should expand form the 2nd column to the last.
Posted on:
10/8/2008 12:00:00 AM
Posted by:
Thank you for providing such a useful example - the level of description is very appreciated.  I do have a couple of questions regarding the child gridview - is there a way to make the 1st column invisible?  Also, can I modify the 2nd column to be a hyperlink?  I''m assuming the autogeneratecolumn setting would be false - however I''m stuck after that.  Thanks again for sharing your knowledge.  Janette
Posted on:
10/8/2008 12:00:00 AM
Posted by:

Before you bind the child grid (NewDG), create an event for it.  such as

GridView
NewDG = new GridView();
NewDG.RowDataBound += new GridViewRowEventHandler(NewDG_RowDataBound); 
//Like wise you could generate other events such as RowCreated and do e.Row.Cell[1].Visible = false; in it

If you created only the first even, then it would create the function for you to use:
void NewDG_RowDataBound(object sender, GridViewRowEventArgs e)
{
      throw new NotImplementedException();
}

In here you can go through the rows, and make it invisible, clear the data, anything you wish. 
Try to create the RowCreated instead and do e.Row.Cell[1].Visible = false;  That may be easier.

Posted on:
10/8/2008 12:00:00 AM
Posted by:
Thanks for your speedy response!  Your solution is great.  I will implement right away.  Thanks again.  Janette
Posted on:
10/8/2008 12:00:00 AM
Posted by:
Thank you for providing such a useful example - the level of description is very appreciated.  I do have a couple of questions regarding the child gridview - is there a way to make the 1st column invisible?  Also, can I modify the 2nd column to be a hyperlink?  I''m assuming the autogeneratecolumn setting would be false - however I''m stuck after that.  Thanks again for sharing your knowledge.  Janette
Posted on:
9/12/2008 12:00:00 AM
Posted by:
Tim
Is there a way to expand or collapse all of the rows at one time? 
Posted on:
9/15/2008 12:00:00 AM
Posted by:
Here is how you can expand all the rows at once: 
1.  Drag a hyperlink column to the page, and give it the following id: 
HLShowALL
2.  Add this code on the Page_Load method, on not postback where the BindData method is:

if ( !Page.IsPostBack )
{
      //Bind Master Details
     
BindData();
      this.HLShowAll.Attributes["onclick"] = "ShowAll(''" + this.DataGrid1.ClientID + "'');";
}

3.  Add the following function to your javascript file:

function
ShowAll(DataGridID)\
{

    var j = 0;
    for( j = 0; j < 10; j++)
    {
        var dataid = "uniquename" + j;
        ShowPanel(dataid);
    }
}


function HideAll(DataGridID)\
{

    var j = 0;
    for( j = 0; j < 10; j++)
    {
        var dataid = "uniquename" + j;
        HidePanel(dataid);
    }
}

Posted on:
8/20/2008 12:00:00 AM
Posted by:
Hi, article was so nice and helped me a lot.
one extra implementation i am adding to this code.
the detail data display style i want to change it to free table style so that the data elements with text could fit in to the area. In other words the detail data elements were with long text. so i want to keep this in vertical column display. how is it possible?.
i tried to keep some repeater control. but couldn''t make it. am unable to send HtmltextWriter to DIvBody.
Could you help me to get this work. i just need the piece of code to create into some kind of form style. Thanks a lot for your time.,

Rgds
pch
Posted on:
8/21/2008 12:00:00 AM
Posted by:
in the item/row databound method, instead of using another grid, create a manual table using a string builder.  next that add that stringbuilder text inside the div.  this should accomplish what you are desiring.  make sure to play around with the table width, and other information to get it perfect.  let me know if this helps.  sorry for the late reply.

Rajib
Posted on:
8/15/2008 12:00:00 AM
Posted by:
Hi Rajib,
Is ther a way  to make the child grid editable, so I can make changes to the data or even add a new record from it? 
 
Thanks,
Alfredo
Posted on:
8/15/2008 12:00:00 AM
Posted by:

This is very difficult.  I usually just add a hyperlink that pulls up a div section.  Then when they click submit, to a postback with the refreshed contents.

Posted on:
8/15/2008 12:00:00 AM
Posted by:
Thanks for your prompt reply. Would you please give me a better idea of how to do that though. Could I do this in the same

GridView1_RowDataBound event?

Posted on:
8/15/2008 12:00:00 AM
Posted by:

In the row databound instead of using a gridview to load your child data, call a function that builds a table.  In the table create for each row create a column that holds the id that unique row.  add a javascript functionality (onclick) that will either launch a new window, redirect to a new window, or pull up a div section prefilled with matching data.  They can be textboxes if you want.  let the user enter the details, and give them a submit button.  Just do a database update when they hit submit, and rebind the hgrid.

Posted on:
8/15/2008 12:00:00 AM
Posted by:

Thanks very much, I would definetly try this and I will let you know afterwards. You are great man... thank you again...

 

Alfredo

Posted on:
8/12/2008 12:00:00 AM
Posted by:
Its working in content placeholder but its not like datagrid..
i mean when there is empty row in second grid then healder of the gridview doesnt appear..
where as in datagrid it use to appear...
Any idea how to make header appear when there is no data in second gridview.????
Posted on:
8/12/2008 12:00:00 AM
Posted by:
Do you want the header to appear or do you want to display some text when the dataset is empty?

To display some text then add NewDG.EmptyDataText = "There is no data to display."

I'm not sure why the headers won't display when the dataset is empty. You could also add NewDG.ShowHeader = True and see if that solves your problem.
Posted on:
8/12/2008 12:00:00 AM
Posted by:
This article is definitely a good one. It''s been very helpful.

I''ve implemented some additional code to add another grid layer (or two, when necessary) and now I want to add a detailsview or similar at the last layer. The detailsview needs to have insert and edit functionality. I can''t seem to find any good references to generate one programmatically like the grid layers are generated. I can create rows, add event handlers and even display the insert row manually but the "Insert" text is not active - there is no link and nothing seems to trigger the even handlers. I was also hoping to generate the rows automatically but I can''t get that to work either.

Any pointers to generating a detailsview completely programmatically without binding to a static datasource?
Posted on:
8/15/2008 12:00:00 AM
Posted by:

Why not just create a table, and code it to add the rows and columns as desired.  This may be an easier approach.  What do you think?

Posted on:
8/11/2008 12:00:00 AM
Posted by:

Hi
its woring fine with master page...but when i inculde master page then problem starts....i have to put full code inside contentplace holder and then problem starts...
Does any one have solution to that???
Can anyone tell me in steps what code to remove from the content placeholder to make it work
Its urgent..
Thanks.

Posted on:
8/11/2008 12:00:00 AM
Posted by:
Sorry..Its not working fine with master page....I forgot to write "NOT"....Plzzzz need help
Posted on:
5/26/2009 12:00:00 AM
Posted by:

hi

is it woking for u ? am using master page in my code. i dont have any guess where am going wrong.

usha

 

Posted on:
8/7/2008 12:00:00 AM
Posted by:
Hi Rajib,
First let me thank you for posting such an interesting and useful solution. I am trying to implement it though and it is not working for me. The script that give me a "+" or "- sign" alternatively is working fine, but I cannot get any data from the subqueries. I have noticed that even if I put a break point to my GridView1_RowDataBound event handler, I dont get there after I click on the plus/minus sign. Correct me if I am wrong but, isnt this the behaviour I should expect?
Can you give me some advise on how could I fix this?

Al
Posted on:
8/7/2008 12:00:00 AM
Posted by:
Al,

First of all thanks for the positive feedback.  The way the code generates is it creates div sections in the datagrid that are hidden (using display: none in the style property).  When you click the [+] or [-] it changes the style to show (display: block in the style property).  Clicking on the [+], [-] only hides/shows using javascript.  This way there is no postback keepings browsers happy.  What may be the problem is that I had set the height to 1px.  C
hange the following line from:

string DivStart = "<DIV id='uniquename"
e.Row.RowIndex.ToString() + 
                  "' style='DISPLAY: none; HEIGHT: 1px;'>"
;
to
string DivStart = "<DIV id='uniquename"
e.Row.RowIndex.ToString() + 
                  "' style='DISPLAY: none;'>"
;

That should solve your problem.  This is in the rowdatabound method.  The Row Databound method occurs when you call the GridView1.DataBind();  Let me know if this helps, or if I can assist you in any other way.

Thanks,

Rajib A.
Posted on:
8/7/2008 12:00:00 AM
Posted by:
Hi Rajib,
 
Thank you very much for your prompt response. I did what you sugested but the behaviour is still the same, "It doesnt show any data afterI click the "+" sign". Now, if I understand what you said correctly, the loading of the data, based on the active row, doesnt happen at the moment you click the sign right?, but when is that this happen then? Maybe I am missing one or two steps in this process.
 
What do you think?
Al 
Posted on:
8/7/2008 12:00:00 AM
Posted by:

Rajib I figured out what the problem was. I had the first three columns of my gridview as invisible so there was no way that I could read their information when the RowDataBound method was executed. I changed them to visible and it worked perfectly.

Thank you very much for your help and keep coming with great solutions like this ok :)

Al 

Posted on:
8/7/2008 12:00:00 AM
Posted by:
Glad you got to solve it.  I'm trying to make this into a reusable control.  Look for it soon...
Posted on:
7/31/2008 12:00:00 AM
Posted by:

This is probably more of a general question but since I was working on this project I thought I''d ask here.

I already have a master page with a treeview control that requires a <form runat="server"> tag. You can have only 1 form per page per page with the runat="server" tag. Without this tag it seems that clicking on the [+] doesn''t display the sub grid (unless I did something else wrong). Do you know of a decent solution to this problem?

Thank you.

Posted on:
8/4/2008 12:00:00 AM
Posted by:
It was me. I forgot to copy the line for the javascript into my page.

In addition to the previous changes mentioned I had to change the ChangePlusMinusText function to look for "<a>[+]</a>" instead of "<A>[+]</A>" in order for the cell's contents to change.

I now have a working copy using VB (without code behind) and a master page. This is a great code sample.Thanks!
Posted on:
8/4/2008 12:00:00 AM
Posted by:

I think even I make that mistake once in a while.  Glad it worked for you.

Posted on:
7/8/2008 12:00:00 AM
Posted by:
Would you happen to have a VB.Net version of the GridView control to show master-child or master-slave data, asp.net, and javascript.
Posted on:
7/8/2008 12:00:00 AM
Posted by:
I have done it for the datagrid, but not the gridview.  http://www.progtalk.com/ViewArticle.aspx?ArticleID=51
I will try to make one for the grid view soon.
Posted on:
7/3/2008 12:00:00 AM
Posted by:
Hi,
I just got this up and running, but I would like add sorting to the gridview. Ive been reading few tutorials about gridview sorting but I am a little bit confused.
The only thing I have is sorting and paging enabled, which makes the headers clickable.
Then I guess I need to define the gridview sorting event to define the direction of the sort (that is I need bi-directional sort)

but what I am not sure about..... do I sort the dataset that I use to assign data to the gridview or the data within the gridview itself?
The .net 2.0 tutorials are really simple, because I should have to code anything.. so Im not exactly sure what I am or should be doing.

I was hoping you would have time to point me towards the solution or the correct way to do this.

by the way... nice contribution!

regards.

Posted on:
7/8/2008 12:00:00 AM
Posted by:

I would recommend sorting the datagrid.  This way the page index can remain the same, but the information is sorted.  Here is a sample code:

        protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)

        {

            string SortBy = "[" + e.SortExpression + "]";

 

            if (ViewState["SortBy"] == null || ViewState["SortBy"].ToString() != SortBy)

            {

                //New Sort Expression

                ViewState["SortBy"] = SortBy;

                ViewState["SortDir"] = "ASC";

            }

            else

            {

                //Same Sort Expression

                if (ViewState["SortDir"] == null)

                {

                    ViewState["SortDir"] = "ASC";

                }

                else if (ViewState["SortDir"].ToString() == "ASC")

                {

                    ViewState["SortDir"] = "DESC";

                }

                else

                {

                    ViewState["SortDir"] = "ASC";

                }

            }

 

            DataSet ds = new DataSet();

            ds = (DataSet)Session["MYDS"];

 

            if (ds != null && ds.Tables.Count > 0)

            {

 

                    DataView dv = new DataView();

                    dv.Table = ds.Tables[0];

                    dv.Sort = ViewState["SortBy"].ToString() + " " + ViewState["SortDir"].ToString();

                    GridView1.DataSource = dv;

                    GridView1.DataBind();

            }

        }

 

Posted on:
6/24/2008 12:00:00 AM
Posted by:
Jay
Hi Rajib its nice article, but i''ve issue regarding with firefox. while i m clicking on [+] it is overlaping on the master grid instead of child grid
any solution???
Posted on:
6/24/2008 12:00:00 AM
Posted by:
Jay
Hi Rajib its nice article, but i''ve issue regarding with firefox. while i m clicking on [+] it is overlaping on the master grid instead of child grid
any solution???
Posted on:
6/24/2008 12:00:00 AM
Posted by:

change the following line from:
string DivStart = "<DIV id='uniquename"
e.Row.RowIndex.ToString() + 
                  "' style='DISPLAY: none; HEIGHT: 1px;'>"
;
to
string DivStart = "<DIV id='uniquename"
e.Row.RowIndex.ToString() + 
                  "' style='DISPLAY: none;'>";

That should solve your problem.  This is in the rowdatabound method.

Posted on:
6/24/2008 12:00:00 AM
Posted by:
Jay
Thank you rajib, it is  working well. there is one more thing that i can show child grid up last second column of the master grid. how i can use it whole space?
Posted on:
6/11/2008 12:00:00 AM
Posted by:
kh
Hi ,
  I wanted to display subTable but having same columns and each column should be displayed under same parent grid. Child talb will not be having any column header. Please do it as it is very urgent for me.
and ther must sorting possible in parent gird only Sub table should but attached to parenttable. if possible please email me the code at nvintt@yahoo.com
.
Posted on:
6/16/2008 12:00:00 AM
Posted by:
This can easily be done by modifying the Datagrid Row DataBound method.  Make sure the new query has the same columns, and you should be able to achieve this goal.
Posted on:
6/3/2008 12:00:00 AM
Posted by:
I want to ask u about how you can hide the textBox "txtExpandedDivs" because i didn''t find any thing do that and no property set to Hidden?
Posted on:
6/3/2008 12:00:00 AM
Posted by:

Just go to the html and look for the div section in the bottom of the page.  Next just change the div style property of display: block to display: none and the textbox will now be shown.  You can also do it manually in the code by doing

TextBox1.Style["display"] = "none";

where TextBox1 will be replaced by txtExpandedDivs

txtExpandedDivs.Style["display"] = "none";

Posted on:
5/29/2008 12:00:00 AM
Posted by:
Hi Rajib,
  Thanks for posting such a nice article.
Can you tell me whether it will work for nested gridview? For example i have nested employee id''s which needs to be drill down once it reches child which doesnt have emoloyee id in child then expand it''s detail? will it be possible for above code?
Thanks in advance

Posted on:
5/30/2008 12:00:00 AM
Posted by:

You can do this by modifying the Row Data Bound method.  Instead of using a grid, use the Tree Control and append nodes to it.  This way it saves some time for coding.  Using the grid itself in the child content may get tedious.

Posted on:
5/20/2008 12:00:00 AM
Posted by:
Hi. I wanted to ask whether this code or the one that you did in the HGrid example support AJAX or not?
Correct me if I am wrong, but you create the rows in the child gridviews in the page load. Do you support that the rows be created only if the row in the original gridview
is explanded?

Thanks in Advance
Posted on:
5/20/2008 12:00:00 AM
Posted by:
The HGrid can support AJAX but no AJAX is used for the expand or collapse feature.  On page load, when it is not a postback, we generate all the rows.  In the databound method we create the child rows and place them inside div's which are hidden to the users eye.  One the page loads, we use javascript to hide and how the divs showing the child entities.  On postback of the page load we check to see what items where already expanded, and reexpanded them to make it user friendly.  This way the page looks the same way when a user had caused a postback.  It does not support that the child rows only be created once the user clicks on the plus or minus.  To do this, it would need a different architecture for the code flow.

Thanks,
Rajib
Posted on:
5/15/2008 12:00:00 AM
Posted by:
Download the code?  Crazy.

Code download doesn''t work when browsing with Firefox and apparently neither with IE6. With IE6 it just dumped me into this comment area and with FF I get dumpted to my site profile area. No code download.
Posted on:
5/15/2008 12:00:00 AM
Posted by:
There was a bug in our system.  Please accept our apologies.  All code should be able to be download now.
Posted on:
5/14/2008 12:00:00 AM
Posted by:
Jim
Hey this is very good.  Someone also sells a server control that works more like a file listing tree
http://www.DigitalTools.com/GVT.aspx
Posted on:
4/29/2008 12:00:00 AM
Posted by:

Excelent work Rajib!

I have found one problem using same technique in my project and i am getting very strange error Undefined clientRects  variable in ScripResource.axd (bold line in follwing code).

Please if any body has got this problem before i am using master pages and ajax on pag.

File ScripResource.axd :
Code where error occurs please scroll down to see blue line.
switch(Sys.Browser.agent) {
    case Sys.Browser.InternetExplorer:
        Sys.UI.DomElement.getLocation = function Sys$UI$DomElement$getLocation(element) {
            /// <param name="element" domElement="true"></param>
            /// <returns type="Sys.UI.Point"></returns>
            var e = Function._validateParams(arguments, [
                {name: "element", domElement: true}
            ]);
            if (e) throw e;

                        if (element.self || element.nodeType === 9) return new Sys.UI.Point(0,0);

                                                var clientRects = element.getClientRects();
            if (!clientRects || !clientRects.length) {
                return new Sys.UI.Point(0,0);
            }

            var w = element.ownerDocument.parentWindow;
                                                var offsetL = w.screenLeft - top.screenLeft - top.document.documentElement.scrollLeft + 2;
            var offsetT = w.screenTop - top.screenTop - top.document.documentElement.scrollTop + 2;

                                                                        var f = w.frameElement || null;
            if (f) {
                                                                                var fstyle = f.currentStyle;
                offsetL += (f.frameBorder || 1) * 2 +
                    (parseInt(fstyle.paddingLeft) || 0) +
                    (parseInt(fstyle.borderLeftWidth) || 0) -
                    element.ownerDocument.documentElement.scrollLeft;
                offsetT += (f.frameBorder || 1) * 2 +
                    (parseInt(fstyle.paddingTop) || 0) +
                    (parseInt(fstyle.borderTopWidth) || 0) -
                    element.ownerDocument.documentElement.scrollTop;
            }

            var clientRect = clientRects[0];

            return new Sys.UI.Point(
                clientRect.left - offsetL,
                clientRect.top - offsetT);
        }
        break;
    case Sys.Browser.Safari:


Thanks in advance

Nazir

Posted on:
5/26/2009 12:00:00 AM
Posted by:
Hi

Did u come out with any solution. I am also having the same problem . am using IE6. How did u sort out the problem?

Regards
Usha
Posted on:
5/29/2009 12:00:00 AM
Posted by:
Hi Usha,

To be honest i don't remember the actual problem but i can remember there could be a problem placing controls in update panel for example you place two controls (popup and extender) in update panel so both controls should be inside the update panel if you put extender outside the update panel you could get this error.

I hope this could give you a clue otherwise send me code i can have a look,

ta
naz
nazeer_rs@yahoo.com

Posted on:
4/22/2008 12:00:00 AM
Posted by:
Ive been looking for a gridview with exactly these features.. Excellent work!

I have a question regarding the first comment made by "(4/10/2008) Walter" in regards to the database. I just downloaded the source code and Im getting the same error as Walter but I cant see that the database is part of the ..hgridview.zip?

Just trying to save some time by not creating it myself. :)
Posted on:
4/22/2008 12:00:00 AM
Posted by:

Thanks for a great feedback.  When creating this sample, I had SQL Server 2005 Express installed on my local with mixed mode, which had Northwind installed on it.  I didn't have the db file attached to the solution.  Do you have a server you can connect to which has Northiwind installed on it?  If so, just modify the connection string, just like Walter, and you should be all set.

Let me know if this doesn't resolve your issue.

Posted on:
4/23/2008 12:00:00 AM
Posted by:
it works, I guess I didnt read the article carefull enough. Didnt realize that northwind was a sample db.
see. http://www.progtalk.com/ViewArticle.aspx?ArticleID=30

Although I changed the connection string :
private string connectionstring = "Server=.\\SQLEXPRESS;Database=Northwind;Integrated Security=SSPI";

and remove the sessionState line from the web.config. Im not exactly sure if that will give me problems later on in regards to different user sessions?


Posted on:
4/23/2008 12:00:00 AM
Posted by:
I am not sure which line had the SessionState.  Can you post the line you removed?
Posted on:
4/28/2008 12:00:00 AM
Posted by:
Sorry for not responding to your reply. I actually dont think this matters at the moment.

But I have another question, Ive been playing around with this code and everything is working good.
Except that I cant set a horizontalAlign.center to a cell in the minigrid (subgrid).

I have a minigrid with 5 columns and I want to set the last column (except for the header) to align center.

I have tried this:
        if (NewDg.Columns.Count > 3)
        {
            NewDg.Columns[4].ItemStyle.HorizontalAlign = HorizontalAlign.Center;
        }

and

        for (int i = 0; i < e.Row.Cells.Count; i++)
        {           
                e.Row.Cells[i].HorizontalAlign = HorizontalAlign.Center;
        }

This is done shortly after you create the newdg gridview. But this results in changing the alignment in the main gridview. Which makes sense but I would think this should also affect the minigrid ?

Posted on:
4/28/2008 12:00:00 AM
Posted by:

You cannot do it with the NewDg.Columns because it will always return 0 because we are dynamically binding.  Here is an alternative below.  I didn't check the GridViewRow Cell Count, but it is a good idea to check for that as well.  Good luck.

NewDg.DataSource = ds;

NewDg.DataBind();

 

foreach (GridViewRow GVR in NewDg.Rows)

{

GVR.Cells[3].HorizontalAlign = HorizontalAlign.Right;

}

 

Posted on:
4/22/2008 12:00:00 AM
Posted by:
M
Rajib,

First of all - great article & smart implementation of good ideas!

I just couldn''t figure how txtExpandedDiv gets data in it. I see txtExpandedDivs.Text = ""; in PageIndexChanging event. But, aside from that I don''t see any real data being assigned to txtExpandedDiv. Am I missing something?

Thanks!
Posted on:
4/22/2008 12:00:00 AM
Posted by:
M
Rajib,

First of all - great article & smart implementation of good ideas!

I just couldn''t figure how txtExpandedDiv gets data in it. I see txtExpandedDivs.Text = ""; in PageIndexChanging event. But, aside from that I don''t see any real data being assigned to txtExpandedDiv. Am I missing something?

Thanks!
Posted on:
4/22/2008 12:00:00 AM
Posted by:

It is actually done in the javascript as the user clicks on the [+], [-].  The method name is
function SetExpandedDIVInfo() in the javascript file.

Thanks for the great feedback.

Posted on:
4/21/2008 12:00:00 AM
Posted by:

Thank you Rajib,
I have solved the problem of index out of range. Now I am thinking about making this sophisticated. I want to have a master row with the data retrieved from the database and the plus sign. The plus sign would be in a column and the master row title would span the rest. The main grid headers would be the headers of the subquery and when sorting, sorting would take place withing the collapsing menus and would not damage the overall structure.

Thank you again.

Posted on:
4/19/2008 12:00:00 AM
Posted by:
Very good article. Works in Opera 9.26, FF 2.0.0.14 and IE7 If... 1. Add the function getElement(aID) 2. Remove the HEIGHT: 1px; (see the other posts) And change the condition: if ( PlusMinusCellObj.innerHTML == "[+]") { PlusMinusCellObj.innerHTML = "[-]"; ... By if (PlusMinusCellObj.innerHTML.indexOf("+") != -1) { PlusMinusCellObj.innerHTML = PlusMinusCellObj.innerHTML.replace("+","-"); And so on. Gracias.
Posted on:
4/16/2008 12:00:00 AM
Posted by:

Hi every body;

Just one thing, very good article, with many comment and who works in some click!

I hope to read some other article by you

Christophe

Posted on:
4/16/2008 12:00:00 AM
Posted by:
Great Job For IE.
Are there any versions for firefox ?

Or can we update javascript for firefox ?
Thanks..
Posted on:
4/16/2008 12:00:00 AM
Posted by:

I think doing the following will make it IE/Mozilla present:

Add this function to the javascript file:

function getElement(aID)
{
    
return (document.getElementById) ? document.getElementById(aID) : getElement[aID];
}

then, in the javascript file, do a find and replace on the following:

Find:   document.all
Replace:  
getElement

This will allow IE and mozilla to work as well as other browsers as far as the javascript.

Now on your c# code, take of the Height: 1px in the Item Databound method of the datagrid. 

That should solve all your problems.
Good luck.

Posted on:
4/16/2008 12:00:00 AM
Posted by:

Hi again,
I think there is a problem with master-page structure.
in js file somethin goes wrong for child-page..

The child row does not seem properly, when i click the [+] label on master row...
Here is the picture of this situation..

Posted on:
4/16/2008 12:00:00 AM
Posted by:

This is happening because of the height = 1px, modify this in the RowDataBound to the following:

string DivStart = "<DIV id='uniquename"e.Row.RowIndex.ToString() + "' style='DISPLAY: none; HEIGHT: 1px;'>";

to

string DivStart = "<DIV id='uniquename"e.Row.RowIndex.ToString() + "' style='DISPLAY: none;'>";

      

Posted on:
4/16/2008 12:00:00 AM
Posted by:
Thanks Rajib
Posted on:
4/15/2008 12:00:00 AM
Posted by:
Hi Rajib,
This is simply Superb ! Awesome !! Hats off to you pal.
Hari.
Posted on:
4/14/2008 12:00:00 AM
Posted by:
Can u please tell me where i can get this text editor???
Posted on:
4/14/2008 12:00:00 AM
Posted by:
Can u please tell me where i can get this text editor???
Posted on:
4/14/2008 12:00:00 AM
Posted by:
Posted on:
4/13/2008 12:00:00 AM
Posted by:
Hi, worked well on Northwind but when I modified the sql datasource and select statements for my database..I got this error "An error has occurred: Specified argument was out of the range of valid values. Parameter name: index"
I assume it is referring to a "Index" field which I don''t have in my database...but I could not find where in the code it is.
Any help?
Posted on:
4/13/2008 12:00:00 AM
Posted by:
I think it is in the row databound method.  Put a break point there, and see what the subquery is.  Did you make sure to change the child sub query in the row databound?
Posted on:
4/21/2008 12:00:00 AM
Posted by:
Thank you for the article firstly. Secondly, I have changed the child subquery and still this exception shows up.

Another thing, I do not want to fix my columns, So they are got from the query. So when I remove <column><column⁄> tags nothing shows up but the button and the labels. But the page does not show any grid view, neither master nor slave. I have done tracing and it is not having much bytes downloaded. Do you have any clue for solving such case.
Posted on:
4/21/2008 12:00:00 AM
Posted by:
Usually the index out of range error comes up when you are trying to fetch data from a column using the e.Item.Cell[YourIndex].Text and that index is greater than the number of columns you have. 

For example, if we had 3 columns, and we did a e.Item.Cell[3].Text, it would throw an index out of range.
This would happen because what we really have are
e.Item.Cell[0]
e.Item.Cell[1]
e.Item.Cell[2]

When you said you took off the column tags, I was a bit confused.  I do not think you need to take those off.  Try a very simple case.  Keep all your columns visible.  Then call the BindData with the ItemDataBound method commented out.  If the grid, and all columns are visible, then enable the ItemDataBound method, and debug through the child query. 

If you follow these steps, you should be set.  If you still get stuck, post some of your code, so I can take a look.

Thanks,
Rajib



Posted on:
4/12/2008 12:00:00 AM
Posted by:

Works Great... thank for the code. Had to convert it to Visual basic and change the  .js to suit my browser but it gave me a new tool to use... Thanks alot.

Posted on:
4/11/2008 12:00:00 AM
Posted by:
Jim

Here is something similar, but they did more like a multi-column treeview.  And made it into a server control.

http://www.digitaltools.com/gvt.aspx

 

 

 

Posted on:
4/11/2008 12:00:00 AM
Posted by:
Great job, except not working in Firefox very well.
Posted on:
4/14/2008 12:00:00 AM
Posted by:
I'll modify the solution so it can work across all browsers.
Posted on:
4/10/2008 12:00:00 AM
Posted by:
Rajib,

      When I run the downloaded source code I got the following error message, Would you help me to solve this problem ?

An error has occurred: An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
Posted on:
4/10/2008 12:00:00 AM
Posted by:

Is your settings for the following line of code correct:

private
string connectionstring = "server=ServerName;database=DB;uid=USERID;password=PASSWORD;";

You have to modify this with your server name, database name, userid, and password.
You should also have mixed mode enabled on your server.

Let me know if this helps.

Posted on:
4/11/2008 12:00:00 AM
Posted by:
ThankYou so much, Rajib; now it works ...
Posted on:
4/11/2008 12:00:00 AM
Posted by:
Glad I could help.

Rajib.