GridView单元格含TextBox时合并列头的实现求助
Got it, let's tackle this GridView header merging problem—especially the scenario where you have TextBoxes in your cells and need to group the last three column headers under a single "Description" header. I've worked through similar cases before, so here are two common implementations depending on what you need exactly, along with all the code you'll need.
Option 1: Two-Tier Header (Main "Description" Header + Sub-Headers)
This is perfect if you want a top-level "Description" header that spans the last three columns, while each of those columns still keeps their own sub-headers (like "Detail 1", "Detail 2", "Detail 3").
Step 1: ASPX GridView Markup
First, define your GridView with manual columns (turn off auto-generation) and include TextBoxes in the last three columns' item templates:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnRowCreated="GridView1_RowCreated" CellPadding="4" ForeColor="#333333"> <Columns> <!-- Regular non-merged columns --> <asp:BoundField DataField="ID" HeaderText="ID" /> <asp:BoundField DataField="ItemName" HeaderText="Item Name" /> <!-- The three columns that fall under "Description" --> <asp:TemplateField HeaderText="Detail 1"> <ItemTemplate> <asp:TextBox ID="txtDetail1" runat="server" Text='<%# Bind("Detail1") %>'></asp:TextBox> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Detail 2"> <ItemTemplate> <asp:TextBox ID="txtDetail2" runat="server" Text='<%# Bind("Detail2") %>'></asp:TextBox> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Detail 3"> <ItemTemplate> <asp:TextBox ID="txtDetail3" runat="server" Text='<%# Bind("Detail3") %>'></asp:TextBox> </ItemTemplate> </asp:TemplateField> </Columns> <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> </asp:GridView>
Step 2: Code-Behind (RowCreated Event)
We'll add a new top-level header row and merge the appropriate cells to create the "Description" span:
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.Header) { // Create a new main header row that sits above the default header GridViewRow mainHeader = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal); // Add cells for the first two columns (no merging needed) TableHeaderCell idCell = new TableHeaderCell(); idCell.Text = "ID"; idCell.ColumnSpan = 1; mainHeader.Cells.Add(idCell); TableHeaderCell nameCell = new TableHeaderCell(); nameCell.Text = "Item Name"; nameCell.ColumnSpan = 1; mainHeader.Cells.Add(nameCell); // Create the merged "Description" cell that spans the last 3 columns TableHeaderCell descriptionCell = new TableHeaderCell(); descriptionCell.Text = "Description"; descriptionCell.ColumnSpan = 3; descriptionCell.HorizontalAlign = HorizontalAlign.Center; mainHeader.Cells.Add(descriptionCell); // Insert the new main header at the top of the GridView's table ((Table)GridView1.Controls[0]).Rows.AddAt(0, mainHeader); } }
Option 2: Single Merged Header (Replace Last Three Headers with "Description")
If you just want the last three columns to share a single "Description" header (no sub-headers), use this simpler approach:
Step 1: ASPX Markup (Same as Option 1)
The GridView structure stays mostly the same—you can even leave the original sub-header texts, since we'll overwrite them in code.
Step 2: Code-Behind (RowCreated Event)
Modify the existing header row to merge the last three cells:
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.Header) { // Target the last three cells in the header row (adjust indexes if your column count differs) int startIndex = 2; // Index of the first column to merge int mergeCount = 3; // Number of columns to merge // Merge the first cell in the range and set its text e.Row.Cells[startIndex].Text = "Description"; e.Row.Cells[startIndex].ColumnSpan = mergeCount; e.Row.Cells[startIndex].HorizontalAlign = HorizontalAlign.Center; // Remove the extra cells that are now merged for (int i = startIndex + mergeCount - 1; i > startIndex; i--) { e.Row.Cells.RemoveAt(i); } } }
Key Notes for TextBox Scenarios
- The TextBoxes in your item templates are completely unaffected by header merging—they'll render and function normally because they're part of the data rows, not the header.
- Make sure
AutoGenerateColumns="False"is set so you have full control over column structure. - Adjust column indexes in the code if your GridView has a different number of columns (the examples assume 5 total columns: 2 non-merged, 3 merged).
内容的提问来源于stack exchange,提问作者Zar

