Pregunta ASP.NET GridView segunda fila de encabezado para abarcar la fila del encabezado principal


Tengo un GridView ASP.NET que tiene columnas que se ven así:

| Foo | Bar | Total1 | Total2 | Total3 |

¿Es posible crear un encabezado en dos filas que se vea así?

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

Los datos en cada fila se mantendrán sin cambios, ya que esto es solo para mejorar el encabezado y disminuir el espacio horizontal que ocupa la cuadrícula.

El GridView completo se puede ordenar en caso de que importe. No pretendo que la columna de extensión "Totales" agregada tenga ninguna funcionalidad de ordenación.

Editar:

Basado en uno de los artículos que figuran a continuación, creé una clase que hereda de GridView y agrega la segunda fila de encabezado.

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 seas nuevo en ASP.NET como yo, también debo señalar que debes:

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.

Simplemente agregue un controlador de eventos para el evento DataBound de su cuadrícula de esta 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 puede ver la fila de encabezado adicional en la vista de diseño de su formulario web. Sin embargo, el método del controlador de eventos es un poco más simple.


32
2017-11-24 16:46


origen


Respuestas:


Este artículo debe apuntarle en la dirección correcta. Puede crear programáticamente la fila y agregarla a la colección en la posición 0.


11
2017-11-24 16:49



Tomé el enfoque de respuesta aceptada, pero agregué el encabezado al GridView existente en lugar de un GridView heredado personalizado.

Después de vincular 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*/

10
2017-11-17 16:02



alt text

Nota para aquellos que eligen usar RowDataBound Method en VB.NET

Si termina con demasiadas filas de encabezado adicionales apareciendo, agregue una instrucción If que solo continúe si la fila de encabezado de gridview no es nada (lo que significa que es la que se está enlazando actualmente)

 If grid.HeaderRow Is Nothing Then

2
2018-01-21 23:04



Deberá crear una clase que extienda gridview y anular el método CreateRow.

tratar esta como punto de partida


1
2017-11-24 16:50



Pero cuando guardas datos, y si ocurre un error en el servidor, se producirán desalineamientos de filas


1
2017-11-19 01:24



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;

1
2018-04-26 11:48



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

Creé este ejemplo de solución

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

  1. GridViewPlus ==> Clase de control
  2. GridViewPlusCustomHeaderRows ==> una colección para mantener la clase de encabezado personalizado
  3. CustomHeaderEventArgs ==> Event Args cuando se crea una fila de encabezado personalizado
  4. archivo 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
2018-02-21 18:06