RowDataBound イベントでグリッドビューからセルから値を取得する
質問
string percentage = e.Row.Cells[7].Text;
GridView で動的なことを実行しようとしているので、RowDataBound イベントにコードを接続しました。TemplateFieldである特定のセルから値を取得しようとしています。しかし、上記のコードは常に空の文字列を返しているようです。
何か案は?
明確にするために、問題のあるセルは次のとおりです。
<asp:TemplateField HeaderText="# Percentage click throughs">
<ItemTemplate>
<%# AddPercentClickThroughs((int)Eval("EmailSummary.pLinksClicked"), (int)Eval("NumberOfSends")) %>
</ItemTemplate>
</asp:TemplateField>
これに関連して、行内のセルを選択するより良い方法があるかどうかを知っている人はいますか。入れるのは面倒だ cell[1]
. 。できなかったのか cell["mycellname"]
, では、セルの順序を変更することにした場合、バグは表示されなくなるのでしょうか?
解決
まずコードをラップする必要があります Label
または Literal
適切に参照できるように制御します。何が起こっているのかというと、テキストに関連付けられたコントロールがないため、システムがそれを追跡する方法がないということです。コンテンツをビューステートに追加するのはコントロールの責任です。
GridView.FindControl("controlName"); を使用する必要があります。行のコントロールを取得します。そこから、次のようなプロパティにアクセスできます。 Text
.
問題の行の DataItem プロパティを取得し、それを適切な型にキャストして、情報を直接抽出することもできます。
他のヒント
データをデータソースから直接取り出さないのはなぜでしょうか。
DataBinder.Eval(e.Row.DataItem, "ColumnName")
TemplateField を使用してリテラル テキストをバインドすると、asp.net は実際にコントロールを挿入します。これは DataBoundLiteralControl に入れられます。これは、デバッガで空のテキストを取得しているコード行の近くを見ると確認できます。
したがって、コントロールを使用するようにテンプレートを変更せずに情報にアクセスするには、次のようにキャストします。
string percentage = ((DataBoundLiteralControl)e.Row.Cells[7].Controls[0]).Text;
これでテキストが得られます。
上記は良い提案ですが、リテラル コントロールやラベル コントロールでラップしなくても、グリッド ビュー内のセルのテキスト値を取得できます。どのイベントを接続するかを知る必要があるだけです。この場合、代わりに次のように DataBound イベントを使用します。
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;
}
}
}
デバッガーを実行すると、このメソッドにテキストが表示されることがわかります。
たとえば、ループを使用してグリッドビューでセルを確認するだけです。
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
}
}
使用 RowDataBound
データをパリシュラーセルでバインドし、制御を使用する機能(ドロップダウンリストのようなASPコントロール名) GridView.FindControl("Name of Control")
同様の質問がありましたが、少し異なるアプローチで解決策を見つけました。Chris が提案したようにコントロールを検索する代わりに、私はまず .aspx ページでフィールドを指定する方法を変更しました。を使用する代わりに、 <asp:TemplateField ...>
タグ、問題のフィールドを使用するように変更しました <asp:BoundField ...>
. 。その後、RowDataBound イベントに到達すると、セル内のデータに直接アクセスできるようになりました。
関連するフラグメント:まず、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>
次に、RowDataBound イベントで値に直接アクセスできます。
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";
}
}
誰かがコメントしてくれるなら なぜ これはうまくいきます、よろしくお願いします。BoundField がないとバインド後のセルに値が存在しない理由は完全には理解できませんが、コントロールを介して値を検索する必要があります。
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");
}
属性を設定すると 見える asp:BoundField で 間違い. 。このような
<asp:BoundField DataField="F1" HeaderText="F1" Visible="False"/>
あなたはするであろう ない 行をループするときに Cells[i].Text プロパティ内の Text を取得します。それで
foreach (GridViewRow row in myGrid.Rows)
{
userList.Add(row.Cells[0].Text); //this will be empty ""
}
ただし、グリッドをイベント OnRowDataBound に接続することで、非表示の列を設定できます。その後、ここからこれを実行します
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);
}
}