Implementation of DataGridView Expansion and Shrinkage Function

  • 2021-07-06 10:41:52
  • OfStack

Many data have parent nodes and child nodes, and we want to expand the child node data under the parent node when we click the parent node.

For example, a hospital department table has a parent department and a sub-department. After clicking the parent department, all the sub-departments under the department can be displayed under the parent department.

Let's talk about how to implement this function in DataGridView.

First, create sample data:

Sample data SQL


create table Department 
( 
 ID int identity(1,1) not null, 
 DName varchar(20) null, 
 DparentId int null, 
 Dtelphone varchar(20) null, 
 Dhospital varchar(50) null 
) 
 
insert into Department values(' Outpatient outpatient room ',1,'1111','XXX Hospital ') 
insert into Department values(' Outpatient internal medicine ',1,'2222','XXX Hospital ') 
insert into Department values(' Outpatient surgery ',1,'3333','XXX Hospital ') 
insert into Department values(' Outpatient pediatrics ',1,'4444','XXX Hospital ') 
insert into Department values(' Internal compartment of nerve ',2,'5555','XXX Hospital ') 
insert into Department values(' Neurosurgery ',2,'6666','XXX Hospital ') 
insert into Department values(' Inpatient operation ',2,'7777','XXX Hospital ') 
insert into Department values(' Hospitalized rehabilitation ',2,'8888','XXX Hospital ') 

In fact, the idea is very simple, that is, when expanding the parent node, insert a new DataGridViewRow; under the parent node; When shrinking the parent node, delete the DataGridViewRow of the child node under the parent node.

For the sake of simplicity, I hard-coded the data reading in the code directly.

To load the parent node data, I added two new columns in addition to those in the database: IsEx and EX.


private void DataGridBing(DataTable table) 
    { 
      if (table.Rows.Count > 0) 
      { 
        for (int i = 0; i < table.Rows.Count; i++) 
        { 
           
          int k = this.dataGridView1.Rows.Add(); 
          DataGridViewRow row = this.dataGridView1.Rows[k]; 
          row.Cells["ID"].Value = table.Rows[i]["ID"]; 
          row.Cells["DName"].Value = table.Rows[i]["DName"]; 
          row.Cells["Daddress"].Value = table.Rows[i]["Daddress"]; 
          row.Cells["Dtelphone"].Value = table.Rows[i]["Dtelphone"]; 
          // Used to show whether the row has been expanded  
          row.Cells["IsEx"].Value = "false"; 
          // Used to display expansion or contraction symbols, I use string directly for simplicity, but it is more beautiful to use pictures  
          row.Cells["EX"].Value = "+"; 
        } 
      } 
    } 

The following is the click event of Cell, in which the insertion of expansion and the deletion of contraction are written respectively.

Insert child nodes:


string isEx=this.dataGridView1.Rows[e.RowIndex].Cells["IsEx"].Value.ToString(); 
      if (this.dataGridView1.Columns[e.ColumnIndex].Name == "EX" && isEx=="false") 
      { 
        string id = this.dataGridView1.Rows[e.RowIndex].Cells["ID"].Value.ToString(); 
        DataTable table = GetDataTable("select * from Department where DparentId="+id); 
        if (table.Rows.Count > 0) 
        { 
          // Insert a row  
          this.dataGridView1.Rows.Insert(e.RowIndex+1, table.Rows.Count); 
          for (int i = 0; i < table.Rows.Count; i++) 
          { 
            DataGridViewRow row = this.dataGridView1.Rows[e.RowIndex + i+1]; 
            row.DefaultCellStyle.BackColor = Color.CadetBlue; 
            row.Cells["ID"].Value = table.Rows[i]["ID"]; 
            row.Cells["DName"].Value = table.Rows[i]["DName"]; 
            row.Cells["Daddress"].Value = table.Rows[i]["Daddress"]; 
            row.Cells["Dtelphone"].Value = table.Rows[i]["Dtelphone"]; 
          } 
        } 
        // Will IsEx Set to true Indicates that the node has been expanded  
        this.dataGridView1.Rows[e.RowIndex].Cells["IsEx"].Value = "true"; 
        this.dataGridView1.Rows[e.RowIndex].Cells["EX"].Value = "-"; 

Delete child nodes:


if (this.dataGridView1.Columns[e.ColumnIndex].Name == "EX" && isEx == "true") 
      { 
        string id = this.dataGridView1.Rows[e.RowIndex].Cells["ID"].Value.ToString(); 
        DataTable table = GetDataTable("select * from Department where DparentId=" + id); 
        if (table.Rows.Count > 0) 
        { 
          // Utilization Remove 
          for (int i = 0; i < table.Rows.Count; i++) 
          { 
            foreach (DataGridViewRow row in this.dataGridView1.Rows) 
            { 
              if (row.Cells["ID"].Value.Equals(table.Rows[i]["ID"])) 
              { 
                this.dataGridView1.Rows.Remove(row); 
              } 
            } 
          } 
        } 
        //// Will IsEx Set to false Indicates that the node has shrunk  
        this.dataGridView1.Rows[e.RowIndex].Cells["IsEx"].Value = "false"; 
        this.dataGridView1.Rows[e.RowIndex].Cells["EX"].Value = "+"; 
      } 

Here, only one row is determined by comparing ID, and there are many loops. Because the child node is next to the parent node, we can determine the number of rows where the child node is located, so it is better to use RemoveAt () method.


// Utilization RemoveAt 
          for (int i = table.Rows.Count; i > 0; i--) 
          { 
            // Delete a row  
            this.dataGridView1.Rows.RemoveAt(i + e.RowIndex); 
          } 

This is done by constantly inserting and deleting, but the interaction with the database becomes very frequent. It would be better to insert once and then achieve our effect by hiding or showing the lines.

To do this, we also add two new columns to grid:

IsInsert: Used to determine whether the row has inserted child node data

RowCount: Used to hold the number of child nodes inserted under the row.

In the method DataGridBing, when you bind data, you should add one more column:


// Insert or not  
row.Cells["IsInsert"].Value = "false"; 

When adding nodes, we need to make one more judgment. If IsInsert is false, data will be inserted, and if true, data will be displayed

Expand Row


if (this.dataGridView1.Columns[e.ColumnIndex].Name == "EX" && isEx=="false") 
      { 
        if (this.dataGridView1.Rows[e.RowIndex].Cells["IsInsert"].Value.ToString() == "false") 
        { 
          string id = this.dataGridView1.Rows[e.RowIndex].Cells["ID"].Value.ToString(); 
          DataTable table = GetDataTable("select * from Department where DparentId=" + id); 
          if (table.Rows.Count > 0) 
          { 
            // Insert a row  
            this.dataGridView1.Rows.Insert(e.RowIndex + 1, table.Rows.Count); 
            for (int i = 0; i < table.Rows.Count; i++) 
            { 
              DataGridViewRow row = this.dataGridView1.Rows[e.RowIndex + i + 1]; 
              row.DefaultCellStyle.BackColor = Color.CadetBlue; 
              row.Cells["ID"].Value = table.Rows[i]["ID"]; 
              row.Cells["DName"].Value = table.Rows[i]["DName"]; 
              row.Cells["Daddress"].Value = table.Rows[i]["Daddress"]; 
              row.Cells["Dtelphone"].Value = table.Rows[i]["Dtelphone"]; 
            } 
            this.dataGridView1.Rows[e.RowIndex].Cells["IsInsert"].Value = "true"; 
            this.dataGridView1.Rows[e.RowIndex].Cells["RowCount"].Value = table.Rows.Count; 
          } 
        } 
        else 
        { 
          // Display data  
          int RowCount = Convert.ToInt32(this.dataGridView1.Rows[e.RowIndex].Cells["RowCount"].Value); 
          for (int i = 1; i <= RowCount; i++) 
          { 
            this.dataGridView1.Rows[e.RowIndex + i].Visible = true; 
          } 
        } 
        // Will IsEx Set to true Indicates that the node has been expanded  
        this.dataGridView1.Rows[e.RowIndex].Cells["IsEx"].Value = "true"; 
        this.dataGridView1.Rows[e.RowIndex].Cells["EX"].Value = "-"; 
      } 

When shrinking, we just hide the rows.

Contraction row


if (this.dataGridView1.Columns[e.ColumnIndex].Name == "EX" && isEx == "true") 
      { 
        int RowCount = Convert.ToInt32(this.dataGridView1.Rows[e.RowIndex].Cells["RowCount"].Value); 
        for (int i = 1; i <= RowCount; i++) 
        { 
          // Hide line  
          this.dataGridView1.Rows[e.RowIndex + i].Visible = false; 
        } 
        //// Will IsEx Set to false Indicates that the node has shrunk  
        this.dataGridView1.Rows[e.RowIndex].Cells["IsEx"].Value = "false"; 
        this.dataGridView1.Rows[e.RowIndex].Cells["EX"].Value = "+"; 
      } 

You know how DataGridView is to achieve expansion and contraction bar, hope you not only know how to achieve but also hands-on experiment 1 time, not waste this site to tidy up this article oh


Related articles: