example - gridview asp.net c# sql server
Obtener valor de una celda desde una vista de cuadrĂcula en el evento RowDataBound (11)
string percentage = e.Row.Cells[7].Text;
Estoy tratando de hacer algunas cosas dinámicas con mi GridView, así que he conectado algún código al evento RowDataBound. Estoy tratando de obtener el valor de una celda particular, que es un TemplateField. Pero el código anterior siempre parece devolver una cadena vacía.
¿Algunas ideas?
Para aclarar, aquí está un poco la celda ofensiva:
<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 hay una mejor manera de seleccionar la celda en la fila? Es una mierda poner en la cell[1]
. ¿No podría hacer la cell["mycellname"]
, así que si decido cambiar el orden de mis celdas, no aparecerán los errores?
¿por qué no extraer los datos directamente de la fuente de datos?
DataBinder.Eval(e.Row.DataItem, "ColumnName")
Cuando utilizas un TemplateField y le atas el texto literal como lo haces, ¡asp.net insertará un control PARA TI! Se pone en un DataBoundLiteralControl. Puede ver esto si busca en el depurador cerca de la línea de código que está recibiendo el texto vacío.
Por lo tanto, para acceder a la información sin cambiar su plantilla para usar un control, debería lanzar de esta manera:
string percentage = ((DataBoundLiteralControl)e.Row.Cells[7].Controls[0]).Text;
¡Eso te dará tu texto!
Lo anterior son buenas sugerencias, 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. Solo tienes que saber qué evento conectar. En este caso, use el evento DataBound en su lugar, 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á que el texto aparece en este método.
Primero, debe ajustar su código en un control de Label
o Literal
para que pueda referenciarlo correctamente. Lo que sucede es que no hay forma de que el sistema realice un seguimiento de ello, porque no hay control asociado con el texto. Es responsabilidad del control agregar su contenido a viewstate.
Necesita usar gridView.FindControl ("controlName"); para obtener el control en la fila. Desde allí puede acceder a sus propiedades, incluido el Text
.
También puede obtener la propiedad DataItem de la fila en cuestión y convertirla al tipo apropiado y extraer la información directamente.
Si establece el atributo Visible en el asp: BoundField en False . Me gusta esto
<asp:BoundField DataField="F1" HeaderText="F1" Visible="False"/>
No obtendrá ningún texto en la propiedad Cells [i] .Text cuando recorra las filas. Asi que
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 grilla al evento OnRowDataBound y luego desde aquí hacer esto
e.Row.Cells[0].Visible = false //now the cell has Text but it''s hidden
Solo 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
}
}
Tenía una pregunta similar, pero encontré la solución a través de un enfoque ligeramente diferente. En lugar de buscar el control como Chris sugirió, primero cambié la forma en que se especificaba el campo en la página .aspx. En lugar de usar una etiqueta <asp:TemplateField ...>
, cambié el campo en cuestión para usar <asp:BoundField ...>
. Luego, cuando llegué al evento RowDataBound, se podía acceder directamente a los datos 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, lo agradecería. No entiendo completamente por qué sin BoundField el valor no está en la celda después del enlace, pero tienes que buscarlo a través del control.
use la función RowDataBound
para vincular datos con una celda perticular y para obtener el uso de control (Nombre de control ASP como DropDownList) GridView.FindControl("Name of Control")
<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");
}
Label lblSecret = ((Label)e.Row.FindControl("lblSecret"));
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);
}
}