Obtener valor de una celda de una vista de cuadrícula en el evento RowDataBound

StackOverflow https://stackoverflow.com/questions/121722

  •  02-07-2019
  •  | 
  •  

Pregunta

string percentage = e.Row.Cells[7].Text;

Estoy intentando hacer algunas cosas dinámicas con mi GridView, así que conecté algo de código al evento RowDataBound.Estoy intentando obtener el valor de una celda en particular, que es TemplateField.Pero el código anterior siempre parece devolver una cadena vacía.

¿Algunas ideas?

Para aclarar, aquí está un poco la celda infractora:

<asp:TemplateField HeaderText="# Percentage click throughs">
<ItemTemplate>
    <%# AddPercentClickThroughs((int)Eval("EmailSummary.pLinksClicked"), (int)Eval("NumberOfSends")) %>
</ItemTemplate>
</asp:TemplateField>

En una nota relacionada, ¿alguien sabe si existe una mejor manera de seleccionar la celda en la fila?apesta ponerlo cell[1].¿No podría hacerlo? cell["mycellname"], entonces, si decido cambiar el orden de mis celdas, ¿no aparecerán errores?

¿Fue útil?

Solución

Primero necesitas envolver tu código en un Label o Literal control para que pueda consultarlo correctamente.Lo que sucede es que el sistema no tiene forma de realizar un seguimiento porque no hay ningún control asociado con el texto.Es responsabilidad del control agregar su contenido a viewstate.

Necesitas usar gridView.FindControl("controlName");para obtener el control en la fila.Desde allí se puede acceder a sus propiedades, incluidas Text.

También puede acceder a la propiedad DataItem de la fila en cuestión, convertirla al tipo apropiado y extraer la información directamente.

Otros consejos

¿Por qué no extraer los datos directamente de la fuente de datos?

DataBinder.Eval(e.Row.DataItem, "ColumnName")

Cuando usa un TemplateField y le vincula texto literal como lo está haciendo, ¡asp.net en realidad insertará un control PARA USTED!Se coloca en DataBoundLiteralControl.Puede ver esto si mira en el depurador cerca de la línea de código que obtiene el texto vacío.

Entonces, para acceder a la información sin cambiar su plantilla para usar un control, debe emitir algo así:

string percentage = ((DataBoundLiteralControl)e.Row.Cells[7].Controls[0]).Text;

¡Eso te dará tu mensaje de texto!

Las sugerencias anteriores son buenas, pero puede obtener el valor de texto de una celda en una vista de cuadrícula sin envolverlo en un control literal o de etiqueta.Sólo tienes que saber qué evento conectar.En este caso, utilice el evento DataBound, así:

protected void GridView1_DataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        if (e.Row.Cells[0].Text.Contains("sometext"))
        {
            e.Row.Cells[0].Font.Bold = true;
        }
    }
}

Al ejecutar un depurador, verá aparecer el texto en este método.

Simplemente use un bucle para verificar su celda en una vista de cuadrícula, por ejemplo:

for (int i = 0; i < GridView2.Rows.Count; i++)
{
    string vr;
    vr = GridView2.Rows[i].Cells[4].Text; // here you go vr = the value of the cel
    if (vr  == "0") // you can check for anything
    {
        GridView2.Rows[i].Cells[4].Text = "Done";
        // you can format this cell 
    }
}

usar RowDataBound función para unir los datos con una celda perticular y para obtener el uso de control (nombre de control ASP como DropdownList) GridView.FindControl("Name of Control")

Tenía una pregunta similar, pero encontré la solución mediante un enfoque ligeramente diferente.En lugar de buscar el control como sugirió Chris, primero cambié la forma en que se especificaba el campo en la página .aspx.En lugar de utilizar un <asp:TemplateField ...> etiqueta, cambié el campo en cuestión para usar <asp:BoundField ...>.Luego, cuando llegué al evento RowDataBound, se pudo acceder a los datos directamente en la celda.

Los fragmentos relevantes:Primero, la página aspx:

<asp:GridView ID="gvVarianceReport" runat="server" ... >
...Other fields...
    <asp:BoundField DataField="TotalExpected" 
     HeaderText="Total Expected <br />Filtration Events" 
     HtmlEncode="False" ItemStyle-HorizontalAlign="Left" 
     SortExpression="TotalExpected" />
...
</asp:Gridview>

Luego, en el evento RowDataBound puedo acceder a los valores directamente:

protected void gvVarianceReport_Sorting(object sender, GridViewSortEventArgs e)
{
    if (e.Row.Cells[2].Text == "0")
    {
        e.Row.Cells[2].Text = "N/A";
        e.Row.Cells[3].Text = "N/A";
        e.Row.Cells[4].Text = "N/A";
    }
}

Si alguien pudiera comentar por qué esto funciona, te lo agradecería.No entiendo completamente por qué sin BoundField el valor no está en la celda después del enlace, pero hay que buscarlo a través del control.

Label lblSecret = ((Label)e.Row.FindControl("lblSecret"));
<asp:TemplateField HeaderText="# Percentage click throughs">
  <ItemTemplate>
    <%# AddPercentClickThroughs(Convert.ToDecimal(DataBinder.Eval(Container.DataItem, "EmailSummary.pLinksClicked")), Convert.ToDecimal(DataBinder.Eval(Container.DataItem, "NumberOfSends")))%>
  </ItemTemplate>
</asp:TemplateField>


public string AddPercentClickThroughs(decimal NumberOfSends, decimal EmailSummary.pLinksClicked)
{
    decimal OccupancyPercentage = 0;
    if (TotalNoOfRooms != 0 && RoomsOccupied != 0)
    {
        OccupancyPercentage = (Convert.ToDecimal(NumberOfSends) / Convert.ToDecimal(EmailSummary.pLinksClicked) * 100);
    }
    return OccupancyPercentage.ToString("F");
}

Si configura el atributo Visible en el asp:BoundField a FALSO.Como esto

<asp:BoundField DataField="F1" HeaderText="F1" Visible="False"/>

Vas a no obtenga cualquier texto en la propiedad Cells[i].Text cuando recorra las filas.Entonces

foreach (GridViewRow row in myGrid.Rows)
{
  userList.Add(row.Cells[0].Text); //this will be empty ""
}

Pero puede configurar una columna no visible conectando la cuadrícula al evento OnRowDataBound y luego desde aquí haga esto

e.Row.Cells[0].Visible = false //now the cell has Text but it's hidden
protected void gvbind_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        e.Row.Attributes["onmouseover"] = "this.style.cursor='hand';";
        e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
        e.Row.Attributes["onclick"] = ClientScript.GetPostBackClientHyperlink(this.gvbind, "Select$" + e.Row.RowIndex);
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top