2008-11-24 26 views
32

Tengo un GridView ASP.NET que tiene columnas que se ven así:segunda fila de cabecera ASP.NET GridView para abarcar fila de encabezado principal

| Foo | Bar | Total1 | Total2 | Total3 | 

¿Es posible crear un encabezado en dos filas que se parece ¿esta?

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

Los datos de cada fila se mantienen sin cambios, ya que es sólo para embellecer la cabecera y disminuyen el espacio horizontal que la red ocupa.

Todo el GridView se puede ordenar en caso de que sea importante. No pretendo que la columna de extensión "Totales" agregada tenga ninguna funcionalidad de ordenación.

Editar:.

Sobre la base de uno de los artículos que figuran a continuación, he creado una clase que hereda de GridView y añade la segunda fila de cabecera en

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); 
     } 
    } 
} 

En caso de que usted es nuevo en ASP.NET como yo, también debo señalar que necesita:

1) Registre su clase agregando una línea como esta a su formulario web:

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

2) Cambie asp: GridView en su marcado anterior para foo: TwoHeadedGridView. No olvides la etiqueta de cierre.

Otra edición:

También puede hacer esto sin crear una clase personalizada.

sólo tiene que añadir un controlador de eventos para el evento DataBound de la rejilla de la siguiente manera:

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); 
     } 
    } 
} 

La ventaja del control personalizado es que se puede ver la fila de encabezado adicional en la vista de diseño del formulario web. Sin embargo, el método del controlador de eventos es un poco más simple.

+0

la respuesta actualizada me ha ayudado mucho, gracias por tomarse el tiempo para documentar que – Alex

+0

Lo mismo digo - gracias por llenar los espacios en blanco – CResults

+0

Nota - me encontré con que tenía que añadir 'row.TableSection = TableRowSection .TableHeader' para que el código funcione sin error – CResults

Respuesta

11

This article debe apuntar en la dirección correcta. Puede crear programáticamente la fila y agregarla a la colección en la posición 0.

+0

¡Gracias! Usé ese enlace para encontrar una solución. –

1

Deberá crear una clase que amplíe gridview y anule el método CreateRow.

tratar this como punto de partida

1

Pero al guardar los datos, y si se produce un error en el servidor, la desalineación de filas se producirá

1

alt text

Nota para los que optan por utilizar Método RowDataBound en VB.NET

Si usted termina con demasiadas filas de encabezado adicional que se levante, añadir una instrucción IF que sólo procede si fila de encabezado del gridview no es nada (lo que significa que es la que actualmente está siendo obligado)

If grid.HeaderRow Is Nothing Then 
9

I tomó el enfoque de respuesta aceptada, pero agregó el encabezado al GridView existente en lugar de un GridView heredado personalizado.

Después de Ato mi GridView, hago lo siguiente:

/*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*/ 
+0

+1, ¡excelente respuesta! – KyleMit

1

Añadir t.EnableViewState = false; después de agregar la fila:

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

favor refiérase a https://stackoverflow.com/a/9333714/1060656

he creado este ejemplo solución

Para ejecutar en su local El sistema necesitará crear 2 archivos (uno para el control y otro para aspx). Puede hacer un proyecto o 2 proyectos.

  1. GridViewPlus ==> clase de control
  2. GridViewPlusCustomHeaderRows ==> una colección para sostener la clase de cabecera personalizada
  3. CustomHeaderEventArgs ==> Args de eventos cuando se crea la fila de cabecera personalizada
  4. aspx ==> programa de prueba

    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

Quería hacer una tarea similar pero requería hacer clic en los botones dentro del encabezado; ninguna de las anteriores funcionó en ese caso ya que los controladores de eventos no estaban conectados (debido a la secuencia de los eventos). Al final usé la etiqueta headertemplate en el campo de plantilla apropiado de la vista de cuadrícula. El html parece un poco más hinchado, pero los eventos permanecen intactos sin ningún código adicional detrás del esfuerzo. Por ejemplo

<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>.... 
Cuestiones relacionadas