web-dev-qa-db-fra.com

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

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

J'essaie de créer des éléments dynamiques 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 cell[1]. Ne pourrais-je pas faire cell["mycellname"], donc si je décide de changer l'ordre de mes cellules, les bugs n'apparaîtront pas?

29
qui

Vous devez d’abord 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.

11
Orion Adrian

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

DataBinder.Eval(e.Row.DataItem, "ColumnName")
49
Stephen Wrighton

Lorsque vous utilisez un TemplateField et y associez du 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 changer votre modèle pour utiliser un contrôle, vous pouvez lancer comme ceci:

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

Cela vous donnera votre texte!

21
Chris

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

Lorsque vous exécutez un débogueur, vous verrez le texte apparaître dans cette méthode.

12
Harry

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

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: Premièrement, 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 vraiment 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.

1
Mark Meuer

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

1
SEO Service
<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");
}
0
user3679550
Label lblSecret = ((Label)e.Row.FindControl("lblSecret"));
0
Vaibhav Saran

Si vous définissez l'attribut Visible sur asp: BoundField à False. Comme ça

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

Vous obtiendrez pas un texte dans la propriété Cells [i] .Text lorsque vous bouclerez les lignes. Alors

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 comme suit.

e.Row.Cells[0].Visible = false //now the cell has Text but it's hidden
0
vemund