2008-11-24 66 views
32

我有一個ASP.NET的GridView它有看起來像這樣的列: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)註冊你的課程,在你的web表格中加入這樣一行:

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

2)將你以前的標記中的asp:GridView改爲foo:TwoHeadedGridView。不要忘記結束標籤。

另一個編輯:

你也可以做到這一點,而無需創建一個自定義類。

只需添加一個事件處理程序爲網格的類似這樣的數據綁定事件:

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表單的設計視圖中的額外的標題行。不過,事件處理程序方法有點簡單。

+0

更新的答案已經幫助我很多,非常感謝您抽出時間來記錄它 – Alex 2009-11-12 17:20:11

+0

同樣在這裏 - 感謝填空題 – CResults 2011-06-02 11:18:01

+0

注 - 我發現我不得不添加`row.TableSection = TableRowSection .TableHeader`代碼無誤地工作 – CResults 2011-06-02 14:20:24

回答

11

This article應該指出你在正確的方向。您可以編程創建該行並將其添加到位置0的集合中。

1

您將不得不創建一個擴展gridview然後重寫CreateRow方法的類。

嘗試this爲起點

1

但是當你保存數據,如果在服務器上發生錯誤時,會出現行的錯位

1

alt text

注意對於那些誰選擇使用VB中的RowDataBound方法。NET

如果你結束了太多額外的標題行彈出,添加一個聲明,如果只有在GridView的標題行是沒有進入(這意味着它是目前被綁定的)

If grid.HeaderRow Is Nothing Then 
9

我採取了接受的答案方法,但將標題添加到現有的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*/ 
1

添加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; 
0

請參考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(); 
    
        } 
    } 
    
0

我想做一個類似的任務,但所需的水箱內點擊按鈕 - 以上都不是作爲事件處理程序沒有連接好(由於事件的測序)這種情況下工作的。最後,我在網格視圖的相應模板字段中使用了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>....