2010-09-29 66 views
29

Quiero ocultar la columna ID en mi GridView, sabía el códigoGridView Ocultar columna por código

GridView1.Columns[0].Visible = false; 

pero la sorpresa fue que mi propiedad recuento de mis columnas GridView es 0 !!! mientras que puedo ver datos en el GridView, entonces ¿alguna idea?

Gracias,

Actualización:

aquí es el código completo para el método que pueblan el GridView

public DataSet GetAllPatients() 
{ 
    SqlConnection connection = new SqlConnection(this.ConnectionString); 

    String sql = "SELECT [ID],[Name],[Age],[Phone],[MedicalHistory],[Medication],[Diagnoses] FROM [dbo].[AwadyClinc_PatientTbl]order by ID desc"; 

    SqlCommand command = new SqlCommand(sql, connection); 

    SqlDataAdapter da = new SqlDataAdapter(command); 

    DataSet ds = new DataSet(); 

    da.Fill(ds); 

    return ds; 

} 
+0

su unión GridView por datatable? por favor agregue su código aquí –

+0

GridView1.DataSource = patientObj.GetAllPatients(). Tablas [0]; GridView1.DataBind(); –

+0

while GetAllPatients() es un método que devuelve el objeto DataSet –

Respuesta

58

GridView.Columns.Count siempre será 0 cuando su GridView tenga su propiedad AutoGenerateColumns establecida en true (el valor predeterminado es true).

Se puede declarar explícitamente sus columnas y establezca la propiedad AutoGenerateColumns a false, o puede utilizar esto en su código subyacente:

GridView.Rows[0].Cells.Count

para obtener el recuento vez que sus datos GridView se ha enlazado la columna, o esto:

protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 
    e.Row.Cells[index].Visible = false; 
} 

para configurar una columna invisible utilizando el evento de su GridView RowDataBound.

2

si quieres ocultar esa columna al rellenar cuadrícula, puede hacerlo en la página aspx misma como esta

<asp:BoundField DataField="test" HeaderText="test" Visible="False" /> 
+2

Esto no es una solución si el desarrollador establece AutoGenerateColumns = "true" – user1093651

+0

¡La pregunta era "por código", no por el lado del cliente! – Fandango68

2

Aquí estoy vinculante del gridview con conjunto de datos así-

GVAnswer.DataSource = DS.Tables[0]; 
GVAnswer.DataBind(); 

Luego, después de

Entonces contamos el número de filas como este en el bucle for

for (int i = 0; i < GVAnswer.Rows.Count; i++) 
{ 

} 

Entonces después de encontrar el encabezado queremos que sea visible

GVAnswer.HeaderRow.Cells[2].Visible = false; 

luego de hacer la visibilidad falsa de esa celda en particular.

El código completo se dan como esto

public void FillGVAnswer(int QuestionID) { try { OBJClsQuestionAnswer = new ClsQuestionAnswer(); DS = new DataSet(); DS = OBJClsQuestionAnswer.GetAnswers(QuestionID); GVAnswer.DataSource = DS.Tables[0]; GVAnswer.DataBind(); if (DS.Tables[0].Rows.Count > 0) { for (int i = 0; i < GVAnswer.Rows.Count; i++) { GVAnswer.HeaderRow.Cells[2].Visible = false; GVAnswer.HeaderRow.Cells[3].Visible = false; GVAnswer.HeaderRow.Cells[6].Visible = false; GVAnswer.HeaderRow.Cells[8].Visible = false; GVAnswer.HeaderRow.Cells[10].Visible = false; GVAnswer.HeaderRow.Cells[11].Visible = false; //GVAnswer.Rows[i].Cells[1].Visible = false; if (GVAnswer.Rows[i].Cells[4].Text == "T") { GVAnswer.Rows[i].Cells[4].Text = "Text"; } else { GVAnswer.Rows[i].Cells[4].Text = "Image"; } if (GVAnswer.Rows[i].Cells[5].Text == "View Image") { HtmlAnchor a = new HtmlAnchor(); a.HRef = "~/ImageHandler.aspx?ACT=AIMG&AID=" + GVAnswer.Rows[i].Cells[2].Text; a.Attributes.Add("rel", "lightbox"); a.InnerText = GVAnswer.Rows[i].Cells[5].Text; GVAnswer.Rows[i].Cells[5].Controls.Add(a); } if (GVAnswer.Rows[i].Cells[7].Text == "Yes") { j++; ViewState["CheckHasMulAns"] = j;// To Chek How Many answer Of a particulaer Question Is Right } GVAnswer.Rows[i].Cells[8].Visible = false; GVAnswer.Rows[i].Cells[3].Visible = false; GVAnswer.Rows[i].Cells[10].Visible = false; GVAnswer.Rows[i].Cells[6].Visible = false; GVAnswer.Rows[i].Cells[11].Visible = false; GVAnswer.Rows[i].Cells[2].Visible = false; } } } catch (Exception ex) { string err = ex.Message; if (ex.InnerException != null) { err = err + " :: Inner Exception :- " + ex.InnerException.Message; } string addInfo = "Error in getting Answers :: -> "; ClsExceptionPublisher objPub = new ClsExceptionPublisher(); objPub.Publish(err, addInfo); } }

9

Algunas de las respuestas que he visto explican cómo hacer el contenido de una celda invisible, pero no la forma de ocultar toda la columna , que es lo que quería hacer.

Si tiene AutoGenerateColumns = "false" y está usando BoundField para la columna que desea ocultar, Bala answer es resbaladizo.Pero si está utilizando TemplateField para la columna, se puede controlar el evento DataBound y hacer algo como esto:

protected void gridView_DataBound(object sender, EventArgs e) 
{ 
    const int countriesColumnIndex = 4; 

    if (someCondition == true) 
    { 
     // Hide the Countries column 
     this.gridView.Columns[countriesColumnIndex].Visible = false; 
    } 
} 

esto puede no ser lo que el PO estaba buscando, pero es la solución que estaba buscando cuando me encontré haciendo la misma pregunta.

16

Puede ocultar una columna específica consultando la colección de control de datos para el texto del encabezado de columna deseado y estableciendo su visibilidad en verdadero.

((DataControlField)gridView.Columns 
       .Cast<DataControlField>() 
       .Where(fld => (fld.HeaderText == "Title")) 
       .SingleOrDefault()).Visible = false; 
24

Esto ayudó para mí

this.myGridview.Columns[0].Visible = false; 

Aquí 0 es el índice de la columna quiero ocultar.

+1

¿Pero qué ocurre si quiere ocultar los controles en esa columna y aún tener acceso a ellos en el código? .Visible lo elimina literalmente del DOM. Lo que necesitamos es un estilo = "pantalla: ninguno". – Fandango68

+0

@ Fandango68 ... ¡Exactamente! Estaba coloreando texto en RowDataBound y necesitaba este campo en particular para existir y estar oculto. –

0

Utilice este código. Esto hace que la columna invisible si está vacío ...

protected void gridview1_DataBound(object sender, EventArgs e) 
    { 
     Boolean hasData = false; 
     for (int col = 0; col < gridview1.HeaderRow.Cells.Count; col++) 
     { 
      for (int row = 0; row < gridview1.Rows.Count; row++) 
      { 
       if (!String.IsNullOrEmpty(gridview1.Rows[row].Cells[col].Text) 
        && !String.IsNullOrEmpty(HttpUtility.HtmlDecode(gridview1.Rows[row].Cells[col].Text).Trim())) 
       { 
        hasData = true; 
        break; 
       } 
      } 

      if (!hasData) 
      { 
       gridview1.HeaderRow.Cells[col].Visible = false; 
       for (int hiddenrows = 0; hiddenrows < gridview1.Rows.Count; hiddenrows++) 
       { 
        gridview1.Rows[hiddenrows].Cells[col].Visible = false; 
       } 
      } 

      hasData = false; 

     } 

    } 
2
private void Registration_Load(object sender, EventArgs e) 
    { 

         //hiding data grid view coloumn 
         datagridview1.AutoGenerateColumns = true; 
          datagridview1.DataSource =dataSet; 
          datagridview1.DataMember = "users"; // users is table name 
          datagridview1.Columns[0].Visible = false;//hiding 1st coloumn coloumn 
          datagridview1.Columns[2].Visible = false; hiding 2nd coloumn 
          datagridview1.Columns[3].Visible = false; hiding 3rd coloumn 
         //end of hiding datagrid view coloumns 

     } 


    } 
0

Hay un pequeño cambio a suceder, no estará bajo RowDataBound, primero todas las filas deben quedar atado, sólo entonces podríamos ocultar eso. Entonces será un método separado después de que la grilla sea dataBound.

+0

Intente leer este http://stackoverflow.com/about para obtener más información sobre las preguntas y respuestas aquí en SO. Tu contribución no responde la pregunta. Es más un comentario, que puede agregar una vez que aumente su reputación: http://stackoverflow.com/faq#reputation –

0

Este fue el código que funcionó para mí cuando la columna Id es desconocida y AutoGenerateColumns == verdadero;

<%@ Page Language="C#" %> 
<%@ Import Namespace="System.Data" %> 
<%@ Import Namespace="System.Drawing" %> 
<html> 
<head runat="server"> 
    <script runat="server"> 
     protected void Page_Load(object sender, EventArgs eventArgs) 
     { 
      DataTable data = new DataTable(); 
      data.Columns.Add("Id", typeof(int)); 
      data.Columns.Add("Notes", typeof(string)); 
      data.Columns.Add("RequestedDate", typeof(DateTime)); 
      for (int idx = 0; idx < 5; idx++) 
      { 
       DataRow row = data.NewRow(); 
       row["Id"] = idx; 
       row["Notes"] = string.Format("Note {0}", idx); 
       row["RequestedDate"] = DateTime.Now.Subtract(new TimeSpan(idx, 0, 0, 0, 0)); 
       data.Rows.Add(row); 
      } 
      listData.DataSource = data; 
      listData.DataBind(); 
     } 

     private void GridView_RowDataBound(object sender, GridViewRowEventArgs e) 
     { 
      foreach (TableCell tableCell in e.Row.Cells) 
      { 
       DataControlFieldCell cell = (DataControlFieldCell)tableCell; 
       if (cell.ContainingField.HeaderText == "Id") 
       { 
        cell.Visible = false; 
        continue; 
       } 
       if (cell.ContainingField.HeaderText == "Notes") 
       { 
        cell.Width = 400; 
        cell.BackColor = Color.Blue; 
        continue; 
       } 
       if (cell.ContainingField.HeaderText == "RequestedDate") 
       { 
        cell.Width = 130; 
        continue; 
       } 
      } 
     } 

    </script> 
</head> 
<body> 
    <form runat="server"> 
     <asp:GridView runat="server" ID="listData" AutoGenerateColumns="True" HorizontalAlign="Left" 
      PageSize="20" OnRowDataBound="GridView_RowDataBound" EmptyDataText="No Data Available." 
      Width="95%"> 
     </asp:GridView> 
    </form> 
</body> 
</html> 
+0

No puede lanzarlo así ... System.InvalidCastException: no se puede lanzar el objeto de escriba 'System.Web.UI.WebControls.TableCell' para escribir 'System.Web.UI.WebControls.DataControlFieldCell' – Ryanb58

+0

El código actualizado que se muestra es una prueba completa de que funciona. El ejemplo de código anterior no pudo ser probado por sí mismo. – James

2

Si desea ocultar una columna por su nombre en lugar de su índice en GridView. Después de crear DataTable o conjunto de datos, usted tiene que encontrar el índice de la columna por su nombre a continuación, guardar el índice en la variable global como ViewStae, Sesión y etc y luego llamarlo en RowDataBound, como el ejemplo:

string headerName = "Id"; 
     DataTable dt = .... ; 

     for (int i=0;i<dt.Columns.Count;i++) 
     { 
      if (dt.Columns[i].ColumnName == headerName) 
      { 
       ViewState["CellIndex"] = i; 

      } 

     } 

    ... GridView_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 

    if (e.Row.RowType == DataControlRowType.Header || e.Row.RowType == DataControlRowType.DataRow || e.Row.RowType == DataControlRowType.Footer) 
    { 

     int index = Convert.ToInt32(ViewState["CellIndex"]); 

     e.Row.Cells[index].Visible = false; 
    }       
} 
1

Lo más Las respuestas aquí no explican: ¿qué sucede si necesita hacer columnas visibles e invisibles, todas basadas en datos dinámicamente? Después de todo, ¿no debería estar GridViews centrado en los datos?

¿Qué sucede si quiere activar o desactivar las columnas en función de sus datos?

Mi Gridview

<asp:GridView ID="gvLocationBoard" runat="server" AllowPaging="True" AllowSorting="True" ShowFooter="false" ShowHeader="true" Visible="true" AutoGenerateColumns="false" CellPadding="4" ForeColor="#333333" GridLines="None" 
      DataSourceID="sdsLocationBoard" OnDataBound="gvLocationBoard_DataBound" OnRowDataBound="gvLocationBoard_RowDataBound" PageSize="15" OnPreRender="gvLocationBoard_PreRender"> 
      <RowStyle BackColor="#F7F6F3" ForeColor="#333333" /> 
      <Columns> 
       <asp:TemplateField HeaderText="StudentID" SortExpression="StudentID" Visible="False"> 
        <ItemTemplate> 
         <asp:Label ID="Label2" runat="server" Text='<%# Eval("StudentID") %>'></asp:Label> 
        </ItemTemplate> 
       </asp:TemplateField> 
       <asp:TemplateField HeaderText="Student" SortExpression="StudentName"> 
        <ItemTemplate> 
         <asp:Label ID="Label3" runat="server" Text='<%# Eval("StudentName") %>'></asp:Label> 
        </ItemTemplate> 
       </asp:TemplateField> 
       <asp:TemplateField HeaderText="Status" SortExpression="CheckStatusName" ItemStyle-HorizontalAlign="Center"> 
        <ItemTemplate> 
         <asp:HiddenField ID="hfStatusID" runat="server" Value='<%# Eval("CheckStatusID") %>' /> 
         <asp:Label ID="Label4" runat="server" Text='<%# Eval("CheckStatusName") %>'></asp:Label> 
        </ItemTemplate> 
       </asp:TemplateField> 
       <asp:TemplateField HeaderText="RollCallPeriod0" Visible="False"> 
        <ItemTemplate> 
         <asp:CheckBox ID="cbRollCallPeriod0" runat="server" /> 
         <asp:HiddenField ID="hfRollCallPeriod0" runat="server" Value='<%# Eval("RollCallPeriod") %>' /> 
        </ItemTemplate> 
        <HeaderStyle Font-Size="Small" /> 
        <ItemStyle HorizontalAlign="Center" /> 
       </asp:TemplateField> 
       <asp:TemplateField HeaderText="RollCallPeriod1" Visible="False"> 
        <ItemTemplate> 
         <asp:CheckBox ID="cbRollCallPeriod1" runat="server" /> 
         <asp:HiddenField ID="hfRollCallPeriod1" runat="server" Value='<%# Eval("RollCallPeriod") %>' /> 
        </ItemTemplate> 
        <HeaderStyle Font-Size="Small" /> 
        <ItemStyle HorizontalAlign="Center" /> 
       </asp:TemplateField> 
     .. 
etc.. 

Nota del ` "RollCallPeriodn", donde 'n' es un número secuencial.

La forma en que lo hago, es por diseño ocultar todas las columnas que sé que van a estar ENCENDIDAS (visible = "verdadero") u OFF (visible = "falso") más tarde, y según mis datos .

En mi caso, quiero mostrar los Períodos del Periodo hasta cierta columna. Así, por ejemplo, si hoy es 09 a.m. a continuación, quiero mostrar períodos de 6 am, 7 am, 8 y las 9, pero no las 10, las 11, etc.

En otros días que quiero para mostrar todos los tiempos. Y así.

Entonces, ¿cómo hacemos esto?

¿Por qué no utilizar PreRender para "restablecer" el Gridview?

protected void gvLocationBoard_PreRender(object sender, EventArgs e) 
{ 
    GridView gv = (GridView)sender; 
    int wsPos = 3; 
    for (int wsCol = 0; wsCol < 19; wsCol++) 
    { 
     gv.Columns[wsCol + wsPos].HeaderText = "RollCallPeriod" + wsCol.ToString("{0,00}"); 
     gv.Columns[wsCol + wsPos].Visible = false; 
    } 
} 

Ahora encender las columnas que necesita en función de encontrar el inicio de la HeaderText y crea la columna visible si el texto del encabezado no es el predeterminado.

protected void gvLocationBoard_DataBound(object sender, EventArgs e) 
    { 
     //Show the headers for the Period Times directly from sdsRollCallPeriods 
     DataSourceSelectArguments dss = new DataSourceSelectArguments(); 
     DataView dv = sdsRollCallPeriods.Select(dss) as DataView; 
     DataTable dt = dv.ToTable() as DataTable; 
     if (dt != null) 
     { 
      int wsPos = 0; 
      int wsCol = 3; //start of PeriodTimes column in gvLocationBoard 
      foreach (DataRow dr in dt.Rows) 
      { 
       gvLocationBoard.Columns[wsCol + wsPos].HeaderText = dr.ItemArray[1].ToString(); 
       gvLocationBoard.Columns[wsCol + wsPos].Visible = !gvLocationBoard.Columns[wsCol + wsPos].HeaderText.StartsWith("RollCallPeriod"); 

       wsPos += 1; 
      } 
     } 
    } 

No voy a revelar el SqlDataSource aquí, pero basta con decir, con la PreRender, puedo restablecer mi GridView y encender las columnas que quiera con las cabeceras que quiero.

Así que la forma en que funciona es que cada vez que selecciona una fecha o períodos de tiempo diferentes para mostrar como encabezados, restablece el GridView al texto de encabezado predeterminado y Visible = "falso" antes de construir el gridview nuevamente. De lo contrario, sin el PreRender, el GridView tendrá los encabezados de los datos anteriores, ya que el código detrás borra la configuración predeterminada.

Cuestiones relacionadas