【问题标题】:ASP.NET GridView second header row to span main header rowASP.NET GridView 第二个标题行跨越主标题行
【发布时间】:2010-09-23 19:19:21
【问题描述】:

我有一个 ASP.NET GridView,它的列如下所示:

| Foo | Bar | Total1 | Total2 | Total3 |

是否可以在两行上创建一个像这样的标题?

|           |  Totals   |    
| Foo | Bar | 1 | 2 | 3 |

每一行中的数据将保持不变,因为这只是为了美化标题并减少网格占用的水平空间。

在重要的情况下,整个 GridView 都是可排序的。我不打算让添加的“总计”跨越列具有任何排序功能。

编辑:

根据下面给出的一篇文章,我创建了一个继承自 GridView 的类,并在其中添加了第二个标题行。

namespace CustomControls
{
    public class TwoHeadedGridView : GridView
    {
        protected Table InnerTable
        {
            get
            {
                if (this.HasControls())
                {
                    return (Table)this.Controls[0];
                }

                return null;
            }
        }

        protected override void OnDataBound(EventArgs e)
        {
            base.OnDataBound(e);
            this.CreateSecondHeader();
        }

        private void CreateSecondHeader()
        {
            GridViewRow row = new GridViewRow(0, -1, DataControlRowType.Header, DataControlRowState.Normal);

            TableCell left = new TableHeaderCell();
            left.ColumnSpan = 3;
            row.Cells.Add(left);

            TableCell totals = new TableHeaderCell();
            totals.ColumnSpan = this.Columns.Count - 3;
            totals.Text = "Totals";
            row.Cells.Add(totals);

            this.InnerTable.Rows.AddAt(0, row);
        }
    }
}

如果您像我一样是 ASP.NET 新手,我还应该指出您需要:

1) 通过在您的网络表单中添加这样的一行来注册您的课程:

<%@ Register TagPrefix="foo" NameSpace="CustomControls" Assembly="__code"%>

2) 将之前标记中的 asp:GridView 更改为 foo:TwoHeadedGridView。不要忘记结束标记。

另一个修改:

您也可以在不创建自定义类的情况下执行此操作。

只需为网格的 DataBound 事件添加一个事件处理程序,如下所示:

protected void gvOrganisms_DataBound(object sender, EventArgs e)
{
    GridView grid = sender as GridView;

    if (grid != null)
    {
        GridViewRow row = new GridViewRow(0, -1,
            DataControlRowType.Header, DataControlRowState.Normal);

        TableCell left = new TableHeaderCell();
        left.ColumnSpan = 3;
        row.Cells.Add(left);

        TableCell totals = new TableHeaderCell();
        totals.ColumnSpan = grid.Columns.Count - 3;
        totals.Text = "Totals";
        row.Cells.Add(totals);

        Table t = grid.Controls[0] as Table;
        if (t != null)
        {
            t.Rows.AddAt(0, row);
        }
    }
}

自定义控件的优点是您可以在 Web 表单的设计视图上看到额外的标题行。不过,事件处理程序方法要简单一些。

【问题讨论】:

  • 更新后的答案对我有很大帮助,感谢您花时间记录它
  • 这里相同 - 感谢您填写空白
  • 注意 - 我发现我必须添加 row.TableSection = TableRowSection.TableHeader 才能使代码正常工作

标签: c# asp.net gridview


【解决方案1】:

我采用了接受的答案方法,但将标题添加到现有的 GridView 而不是自定义继承的 GridView。

绑定 GridView 后,我执行以下操作:

/*Create header row above generated header row*/

//create row    
GridViewRow row = new GridViewRow(0, -1, DataControlRowType.Header, DataControlRowState.Normal);

//spanned cell that will span the columns I don't want to give the additional header 
TableCell left = new TableHeaderCell();
left.ColumnSpan = 6;
row.Cells.Add(left);

//spanned cell that will span the columns i want to give the additional header
TableCell totals = new TableHeaderCell();
totals.ColumnSpan = myGridView.Columns.Count - 3;
totals.Text = "Additional Header";
row.Cells.Add(totals);

//Add the new row to the gridview as the master header row
//A table is the only Control (index[0]) in a GridView
((Table)myGridView.Controls[0]).Rows.AddAt(0, row);

/*fin*/

【讨论】:

    【解决方案2】:

    This article 应该为您指明正确的方向。您可以以编程方式创建行并将其添加到位置 0 的集合中。

    【讨论】:

    • 谢谢!我使用该链接提出了解决方案。
    【解决方案3】:

    在VB.NET中选择使用RowDataBound方法的注意

    如果您最终弹出了太多额外的标题行,请添加一个 If 语句,该语句仅在 gridview 的标题行没有任何内容(意味着它是当前被绑定的行)时才继续

     If grid.HeaderRow Is Nothing Then
    

    【讨论】:

      【解决方案4】:

      您必须创建一个扩展 gridview 的类,然后覆盖 CreateRow 方法。

      尝试以this 为起点

      【讨论】:

        【解决方案5】:

        添加行后添加t.EnableViewState = false;:

        Dim t As Table = TryCast(grid.Controls(0), Table)
        If t IsNot Nothing Then
            t.Rows.AddAt(0, row)
        End If
        
        t.EnableViewState = false;
        

        【讨论】:

          【解决方案6】:

          请参考https://stackoverflow.com/a/9333714/1060656

          我创建了这个解决方案示例

          要在本地系统中运行,需要创建 2 个文件(一个用于控件,一个用于 aspx),您可以创建一个项目或 2 个项目。

          1. GridViewPlus ==> 控件类
          2. GridViewPlusCustomHeaderRows ==> 保存自定义标头类的集合
          3. CustomHeaderEventArgs ==> 创建自定义标题行时的事件参数
          4. aspx 文件 ==> 测试程序

            public class GridViewPlus : GridView
            {
            
                public event EventHandler<CustomHeaderEventArgs> CustomHeaderTableCellCreated;
            
                private GridViewPlusCustomHeaderRows _rows;
            
                public GridViewPlus() : base ()
                {
                    _rows = new GridViewPlusCustomHeaderRows();
                }
            
                /// <summary>
                /// Allow Custom Headers
                /// </summary>
                public bool ShowCustomHeader { get; set; }
            
            
                [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
                [MergableProperty(false)]
                public GridViewPlusCustomHeaderRows CustomHeaderRows
                {
                    get {return  _rows; }
            
                }
            
                protected virtual void OnCustomHeaderTableCellCreated(CustomHeaderEventArgs e)
                {
                    EventHandler<CustomHeaderEventArgs> handler = CustomHeaderTableCellCreated;
            
                    // Event will be null if there are no subscribers
                    if (handler != null)
                    {
                        // Use the () operator to raise the event.
                        handler(this, e);
                    }
            
                }
            
                protected override void OnRowCreated(GridViewRowEventArgs e)
                {
                    if (ShowCustomHeader && e.Row.RowType == DataControlRowType.Header) return;
                    base.OnRowCreated(e);
                }
            
            
                protected override void PrepareControlHierarchy()
                {
                    //Do not show the Gridview header if show custom header is ON
                    if (ShowCustomHeader) this.ShowHeader = false;
            
            
                    base.PrepareControlHierarchy();
                    //Safety Check
                    if (this.Controls.Count == 0)
                        return;
                    bool controlStyleCreated = this.ControlStyleCreated;
                    Table table = (Table)this.Controls[0];
            
                    int j = 0;
                    if (CustomHeaderRows ==null )return ;
            
                    foreach (TableRow tr in CustomHeaderRows)
                    {
                        OnCustomHeaderTableCellCreated(new CustomHeaderEventArgs(tr,j));
                        table.Rows.AddAt(j, tr);
                        tr.ApplyStyle(this.HeaderStyle);
                        j++;
                    }
            
            
                }
            }
            
            public class GridViewPlusCustomHeaderRows : System.Collections.CollectionBase
            {
                public GridViewPlusCustomHeaderRows()
                {
                }
            
                public void Add(TableRow aGridViewCustomRow)
                {
                    List.Add(aGridViewCustomRow);
                }
            
                public void Remove(int index)
                {
                    // Check to see if there is a widget at the supplied index.
                    if (index > Count - 1 || index < 0)
                    // If no widget exists, a messagebox is shown and the operation 
                    // is cancelled.
                    {
                        throw (new Exception("Index not valid"));
                    }
                    else
                    {
                        List.RemoveAt(index);
                    }
                }
            
                public TableRow Item(int Index)
                {
                    // The appropriate item is retrieved from the List object and
                    // explicitly cast to the Widget type, then returned to the 
                    // caller.
                    return (TableRow)List[Index];
                }
            
            }
            
            
            public class CustomHeaderEventArgs : EventArgs
            {
                public CustomHeaderEventArgs(TableRow tr ,int RowNumber  )
                {
                    tRow = tr;
                    _rownumber = RowNumber;
                }
                private TableRow tRow;
                private int _rownumber = 0;
            
            
                public int RowNumber { get { return _rownumber; } }
            
                public TableRow HeaderRow
                {
                    get { return tRow; }
                    set { tRow = value; }
                }
            
            
            }
            
            
            public partial class _Default : System.Web.UI.Page
            {
                protected void Page_Load(object sender, EventArgs e)
                {
                    Example1();
                    GridViewExtension1.CustomHeaderTableCellCreated += new EventHandler<CustomHeaderEventArgs>(GridViewExtension1_CustomHeaderTableCellCreated);
                }
            
                void GridViewExtension1_CustomHeaderTableCellCreated(object sender, CustomHeaderEventArgs e)
                {
                    TableRow tc = (TableRow)e.HeaderRow;
            
                    tc.BackColor = System.Drawing.Color.AliceBlue;
                }
            
                private void Example1()
                {
                    System.Data.DataTable dtSample = new DataTable();
                    DataColumn dc1 = new DataColumn("Column1",typeof(string));
                    DataColumn dc2 = new DataColumn("Column2",typeof(string));
                    DataColumn dc3 = new DataColumn("Column3",typeof(string));
                    DataColumn dc4 = new DataColumn("Column4",typeof(string));
                   // DataColumn dc5 = new DataColumn("Column5",typeof(string));
                    dtSample.Columns.Add(dc1);
                    dtSample.Columns.Add(dc2);
                    dtSample.Columns.Add(dc3);
                    dtSample.Columns.Add(dc4);
                   // dtSample.Columns.Add(dc5);
                    dtSample.AcceptChanges();
            
                    for (int i = 0; i < 25; i++)
                    {
                        DataRow dr = dtSample.NewRow();
            
                        for (int j = 0; j < dtSample.Columns.Count; j++)
                        {
                            dr[j] = j;
                        }
                        dtSample.Rows.Add(dr);
                    }
                    dtSample.AcceptChanges();
                    //GridViewExtension1.ShowHeader = false;
                    GridViewExtension1.ShowCustomHeader = true;
            
                    /*
                     *=======================================================================
                     *  |Row 1 Cell 1   |   Row 1 Col 2 (Span=2)        | Row 1 Col 3   |
                     *  |               |                               |               |
                     *=======================================================================             
                     *  |Row 2 Cell 1   |               |               |               |
                     *  |               |   Row 2 Col 2 | Row 2 Col 3   |Row 2 Col 4    |
                     *=======================================================================
                     * 
                     * 
                     * 
                     * 
                     * */
            
                    // SO we have to make 2 header row as shown above
            
                    TableRow TR1 = new TableRow();
                    TableCell tcR1C1 = new TableCell();
                    tcR1C1.Text = "Row 1 Cell 1";
                    tcR1C1.ColumnSpan = 1;
                    TR1.Cells.Add(tcR1C1);       
            
                    TableCell tcR1C2 = new TableCell();
                    tcR1C2.Text = "Row 1 Cell 2";
                    tcR1C2.ColumnSpan = 2;
                    TR1.Cells.Add(tcR1C2);  
            
                    TableCell tcR1C3 = new TableCell();
                    tcR1C3.Text = "Row 1 Cell 3";
                    tcR1C3.ColumnSpan = 1;
                    TR1.Cells.Add(tcR1C3);
            
            
                    GridViewExtension1.CustomHeaderRows.Add(TR1);
            
                    TableRow TR2 = new TableRow();
                    TableCell tcR2C1 = new TableCell();
                    tcR2C1.Text = "Row 2 Cell 1";
                    tcR2C1.ColumnSpan = 1;
                    TR2.Cells.Add(tcR2C1);
            
                    TableCell tcR2C2 = new TableCell();
                    tcR2C2.Text = "Row 2 Cell 2";
                    tcR2C2.ColumnSpan = 1;
                    TR2.Cells.Add(tcR2C2);
            
                    TableCell tcR2C3 = new TableCell();
                    tcR2C3.Text = "Row 2 Cell 3";
                    tcR2C3.ColumnSpan = 1;
                    TR2.Cells.Add(tcR2C3);
            
                    TableCell tcR2C4 = new TableCell();
                    tcR2C4.Text = "Row 2 Cell 4";
                    tcR2C4.ColumnSpan = 1;
                    TR2.Cells.Add(tcR2C4);
            
                    GridViewExtension1.CustomHeaderRows.Add(TR2);
            
            
                    GridViewExtension1.DataSource = dtSample;
                    GridViewExtension1.DataBind();
            
                }
            }
            

          【讨论】:

            【解决方案7】:

            我想做一个类似的任务,但需要标题内的可点击按钮 - 在这种情况下,以上都不起作用,因为事件处理程序没有连接(由于事件的顺序)。最后,我在网格视图的相应模板字段中使用了 headertemplate 标记。 html 看起来有点臃肿,但事件保持不变,无需额外的代码。例如

            <asp:TemplateField >
                         <HeaderTemplate>
                           <div>
                            <div style="text-align: center;padding-bottom: 5px;">
                                                                      text
                               </div>
                                <div>
                                 <asp:Button ID="Button1" runat="server" Text="Apply to all" ToolTip="Apply to all - Special Bolt On" CssClass="sub_button input_btn_5" OnClick="ApplyButton1_Click" />
                               </div>
                              </div>
                              </HeaderTemplate>
                              <ItemTemplate>....
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-09-27
              • 1970-01-01
              • 2013-07-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多