Obtention de la valeur d'une cellule à partir d'un gridview sur un événement RowDataBound

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

  •  02-07-2019
  •  | 
  •  

Question

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

J'essaie de créer du contenu dynamique avec GridView. J'ai donc câblé du code à l'événement RowDataBound. J'essaie d'obtenir la valeur d'une cellule particulière, qui est un TemplateField. Mais le code ci-dessus semble toujours renvoyer une chaîne vide.

Des idées?

Pour clarifier, voici un peu la cellule incriminée:

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

Sur une note connexe, est-ce que quelqu'un sait s'il existe un meilleur moyen de sélectionner la cellule dans la rangée. Ça craint de mettre en cell[1]. Est-ce que je ne pourrais pas le faire cell["mycellname"], donc si je décide de changer l'ordre de mes cellules, les bogues n'apparaîtront pas?

Était-ce utile?

La solution

Tout d'abord, vous devez envelopper votre code dans un contrôle Label ou Literal afin de pouvoir le référencer correctement. Ce qui se passe, c'est qu'il n'y a aucun moyen pour le système de garder trace de cela, car aucun contrôle n'est associé au texte. Il incombe au contrôle d’ajouter son contenu à viewstate.

Vous devez utiliser gridView.FindControl (" controlName "); pour obtenir le contrôle dans la rangée. De là, vous pouvez accéder à ses propriétés, y compris Text.

Vous pouvez également accéder à la propriété DataItem de la ligne en question, lui attribuer le type approprié et extraire directement les informations.

Autres conseils

pourquoi ne pas extraire les données directement de la source de données.

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

Lorsque vous utilisez un TemplateField et que vous lui associez un texte littéral comme vous le faites, asp.net insérera un contrôle POUR VOUS! Il est mis dans un DataBoundLiteralControl. Vous pouvez le voir si vous regardez dans le débogueur à proximité de votre ligne de code contenant le texte vide.

Ainsi, pour accéder aux informations sans modifier votre modèle pour utiliser un contrôle, vous devez définir le format suivant:

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

Cela vous permettra d'obtenir votre texte!

Les suggestions ci-dessus sont de bonnes suggestions, mais vous pouvez obtenir la valeur de texte d'une cellule dans une vue de grille sans l'envelopper dans un contrôle littéral ou avec une étiquette. Vous devez juste savoir quel événement connecter. Dans ce cas, utilisez plutôt l'événement DataBound, comme suit:

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

Lors de l'exécution d'un débogueur, le texte apparaît dans cette méthode.

Utilisez simplement une boucle pour vérifier votre cellule dans un gridview, par exemple:

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

utilisez RowDataBound la fonction pour lier des données à une cellule particulière et pour obtenir un contrôle (Nom du contrôle ASP comme DropDownList) GridView.FindControl("Name of Control")

J'avais une question similaire, mais j'ai trouvé la solution en adoptant une approche légèrement différente. Au lieu de rechercher le contrôle comme suggéré par Chris, j'ai d'abord modifié la façon dont le champ a été spécifié dans la page .aspx. Au lieu d'utiliser une balise <asp:TemplateField ...>, j'ai changé le champ en question pour utiliser <asp:BoundField ...>. Ensuite, lorsque je suis arrivé à l'événement RowDataBound, les données étaient directement accessibles dans la cellule.

Les fragments pertinents: en premier lieu, la page 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>

Ensuite, dans l'événement RowDataBound, je peux accéder directement aux valeurs:

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 quelqu'un pouvait commenter pourquoi cela fonctionne, je l'apprécierais. Je ne comprends pas bien pourquoi, sans BoundField, la valeur ne se trouve pas dans la cellule après la liaison, mais vous devez la rechercher via le contrôle.

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 vous définissez l'attribut Visible sur asp: BoundField sur False . Comme ça

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

Vous ne obtiendrez aucun texte dans la propriété Cells [i] .Text lorsque vous bouclerez les lignes. Donc

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

Mais vous pouvez définir une colonne non visible en connectant la grille à l'événement OnRowDataBound, à partir de là, procédez ainsi

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);
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top