Can't read Label value in GridView - c#

I have read many posts here looking for the answer. But no matter what I do I always get a null value returned for my Label.
I can populate it just fine and read it at that time, but when I try to read the label to populate DB it is always null.
aspx code:
<asp:TemplateField HeaderText="TOTAL YIELD" ItemStyle-HorizontalAlign="Center" HeaderStyle-Width="130">
<EditItemTemplate>
<asp:Label ID="lb_TotalYield" runat="server" ></asp:Label>
</EditItemTemplate>
</asp:TemplateField>
in the code behind I am just trying to read it.
foreach (GridViewRow currentRow in gv_Fruit.Rows)
{
Label tempLabel = (Label)currentRow.FindControl("lb_TotalValue") as Label;
string theTotalValue = tempLabel.Text;
}
for complete information Here is how I set the label:
myGridView.SelectedRow.Cells[4].Text = myTotalYield;
I have tried doing a gv_RowDataBound, but it doesn't seem to ever be called.
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (myGridView.EditIndex == e.Row.RowIndex &&
e.Row.RowType == DataControlRowType.DataRow)
{
Label mylabel = (Label)e.Row.FindControl("lb_TotalYield");
mylabel.DataBind();
}
}

Related

Can't Find Hyperlink of Cell during Gridview RowDatabound

I have a gridview that lists rows of information from SQL. If the late column is set to 1 it should display the text of the row in red. This works, however the hyperlink text will not be displayed in red. So I'm trying to a) change the forecolor of the hyperlink element or b) apply a class to the element. When I try to retrieve the hyperlink it does not get it. When I retrieve a label it seems to work fine.
ASP
<asp:TemplateField HeaderText="Project">
<ItemTemplate>
<a id="hlProject" href="VpnDetails.aspx?Project=<%# Eval("id") %>"><%# Eval("project") %></a>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Last Update">
<ItemTemplate>
<asp:Label ID="lblLastUpdate" runat="server" Text='<%#Eval("diff") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
C#
protected void gvLastIp_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Adds the tooltip to the last update label
Label lblLastUpdate = e.Row.FindControl("lblLastUpdate") as Label;
DateTime activeSince = Convert.ToDateTime(DataBinder.Eval(e.Row.DataItem, "begindate"));
DateTime lastupdate = Convert.ToDateTime(DataBinder.Eval(e.Row.DataItem, "lastupdate"));
lblLastUpdate.ToolTip = "Active Since " + activeSince.ToString("MMMM d yyyy HH:mm") + " - Last Update " + lastupdate.ToString("MMMM d yyyy HH:mm");
if (Convert.ToString(DataBinder.Eval(e.Row.DataItem, "late")) == "1")
{//if the row is late it should be red
e.Row.Font.Bold = true;
e.Row.ForeColor = System.Drawing.Color.Red;
HyperLink hlProject = new HyperLink();
try
{
hlProject = (HyperLink)e.Row.FindControl("hlProject");
hlProject.Attributes.Add("class", "late");
hlProject.ForeColor = System.Drawing.Color.Red;
}
catch (Exception e1)
{
lblError.Text = e1.Message;
}
}
}
So I need to know why it works for the label and not for the hyperlink. I also need a solution for the hyperlink.
You can't find your hyperlink on the server because it is not a server side control. You need to add runat="server" to do just that. Note the change to the href to make it valid.
<a id="hlProject" runat="server" href='<%# Eval("id", "VpnDetails.aspx?Project={0}") %>'><%# Eval("project") %></a>
You would then be able to grab it server side by finding it within your row.
using System.Web.UI.HtmlControls;
protected void gvLastIp_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HtmlAnchor hlProject = (HtmlAnchor)e.Row.FindControl("hlProject");
}
}
Alternatively, you could create and use an ASP.NET Hyperlink control. This is a little more flexible/useful on the server side.
<asp:HyperLink ID="hlProject" runat="server"
NavigateUrl='<%# Eval("id", "VpnDetails.aspx?Project={0}") %>'
Text='<%# Eval("project") %>'>
</asp:HyperLink>
protected void gvLastIp_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink hlProject = (HyperLink)e.Row.FindControl("hlProject");
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink myHyperLink = e.Row.FindControl("myHyperLinkID") as HyperLink;
}
}
This should work.

Disable gridview rows based on database table column value

I have a gridview which is being loaded from database table.
There is one column in the table named 'valid',whose values are 'Y' or 'N'.
Now, what I want to do is, to check if the value of 'valid' is Y, then the whole record in that row should appear as disabled when loading the gridview.
How to proceed with that? should I write a procedure for this or it can be done from code behind?
Note: the column Valid is not a part of gridview.
You need to use RowDataBound event of gridview to disable rows.
Note that if you use databound columns then it is rendered in tr and td then you need to find the cell and then set the disable property.
protected void gvEntity_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//CheckBox cbAttachClrReq = (CheckBox) e.Row.FindControl("chkAdd");
//check the value here and set enable property
e.Row.Enabled = false;
}
}
As #Hanlet EscaƱo has suggested you can add the field value in the same column as follows
<asp:TemplateField>
<ItemTemplate>
<<asp:Label ID="lbl1" runat="server"
Value='<%# Eval("Name") %>' />
<asp:HiddenField ID="HiddenField1" runat="server"
Value='<%# Eval("valid") %>' />
</ItemTemplate>
and get the hidden field value in row-databound event as follows
protected void gvEntity_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HiddenField Hf = (HiddenField) e.Row.FindControl("HiddenField1");
if(Hf.Value=="Y")
e.Row.Enabled = false;
}
}
Try the following.
This example gets the DataRowView per record and then extracts the valid column from the underlying datasource to test against.
protected void grdDetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var dr = e.Row.DataItem as DataRowView;
if(Convert.ToString(dr["valid"]) == 'Y')
e.Row.Enabled = false;
}
}
and the markup
<asp:GridView ID="grdDetails" runat="server" OnRowDataBound="grdDetails_RowDataBound"

GridView row won't disable

I am trying to disable a specific grdview row using the code below, but it isn't disabling that row. I am 100% sure there is a value called "Total Expenses" in the column that is bound to the gridview. What is more strange is that, I removed the if condition(accountTextBox.Text == "Total Expenses") to see if all the rows get disabled but only the first row is getting disabled. Any thoughts on this?
More information: Am using gridview with template fields(ASP.NET, C#). I also ran debugger and found that the accountTextBox is showing NULL. Am puzzled!
I appreciate any thoughts you may have. Thank you
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
if (!tableCopied)
{
originalDataTable = ((System.Data.DataRowView)e.Row.DataItem).Row.Table.Copy();
ViewState["originalValuesDataTable"] = originalDataTable;
tableCopied = true;
TextBox accountTextBox = (TextBox)e.Row.FindControl("AccountTextBox");
if (accountTextBox.Text == "Total Expenses")
{
e.Row.Enabled = false;
}
}
}
I'm assuming your markup looks something like this:
<asp:TemplateField HeaderText="SomeField" SortExpression="SomeField">
<EditItemTemplate>
<asp:TextBox ID="AccountTextBox" runat="server" Text='<%# Bind("SomeField") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("SomeField") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
In which case AccountTextBox will only be available in RowDataBound when e.Row.State is in Edit mode. which may or may not be available depending what update functionality is provided in your datasource...but that's something else.
Typically you don't use a TextBox to display data but lets say trying to populate a "readonly" TextBox then all you need do is move AccountTextBox from the EditTemplate to the ItemTemplate and you should be good to go.
Using the following code-behind:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
gvTest.DataSource = new List<string>() { "test1", "test2" };
gvTest.DataBind();
}
private bool tableCopied = false;
private System.Data.DataTable originalDataTable;
protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
if (!tableCopied)
{
//originalDataTable = ((System.Data.DataRowView)e.Row.DataItem).Row.Table.Copy();
//ViewState["originalValuesDataTable"] = originalDataTable;
//tableCopied = true;
TextBox accountTextBox = (TextBox)e.Row.FindControl("AccountTextBox");
if (accountTextBox.Text == "Total Expenses")
{
e.Row.Enabled = false;
}
}
}
}
And this markup:
<asp:GridView runat="server" ID="gvTest" OnRowDataBound="gvTest_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="AccountTextBox" runat="server">Total Expenses</asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I am not reproducing the bug. Both rows disable for me.
The tableCopied variable could be the problem. It will be set to true on the first row and this will restrict the remaining rows to enter the if condition and actually be disabled.
First row:
//tableCopied is false
if(!tableCopied) // pass
tableCopied = true
Other rows:
//tableCopied is true
if(!tableCopied) // wont pass
Note that the GridView1_RowDataBound event occurs once for every row on the same postback and every class member is persisted during the postback.

Can not find a control using the FindControl on RowCreated for Gridview

I am using a gridview, and here is one of my templatefields:
<asp:TemplateField HeaderText="Quantity" SortExpression="Quantity">
<HeaderTemplate>
<asp:Label ToolTip="Quantity" runat="server" Text="Qty"></asp:Label>
</HeaderTemplate>
<EditItemTemplate>
<asp:TextBox ID="txt_Quantity" runat="server" Text='<%# Bind("Quantity") %>' Width="30px"
Enabled='True'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
I am tring to reach txt_Quantity like this
protected void begv_OrderDetail_RowCreated(object sender, GridViewRowEventArgs e)
{
TextBox txt_Quantity = (TextBox)e.Row.FindControl("txt_Quantity");
txt_Quantity.Attributes.Add("onFocus", "test(this)");
}
This is the error message:
System.NullReferenceException: Object reference not set to an instance
of an object.
RowCreated is executed for every RowType(btw, the same as with RowDataBound), so for the header, data-row, footer or pager.
The first row is the header-row, but the TextBox is in rows with RowType=DataRow. Since it's in the EditItemTemplate you also have to check the EditIndex:
protected void begv_OrderDetail_RowCreated(object sender, GridViewRowEventArgs e)
{
if (row.RowType == DataControlRowType.DataRow
&& e.Row.RowIndex == begv_OrderDetail.EditIndex)
{
TextBox txt_Quantity = (TextBox)e.Row.FindControl("txt_Quantity");
txt_Quantity.Attributes.Add("onFocus", "test(this)");
}
}
Note that if you enumerate the Rows property of the GridView you only get the rows with RowType=DataRow, so the header, footer and pager are omitted. So here no additional check is needed:
foreach(GridViewRow row in begv_OrderDetail.Rows)
{
// only DataRows
}

GridView Conditional Button Visibility

I have this itemtemplate for a gridview column that is pulling data from a SQL database. My Question is how would I perform a check to see if my field ActivityFile has a value (which means a file is in the db) and then display the LinkButton at which point I generate code to download the file (already done and works).
<ItemTemplate>
<asp:LinkButton ID="DownloadFileBtn" runat="server" visible="false">Download File</asp:LinkButton>
<br />
<asp:Label ID="Label4" runat="server" Text='<%# Bind("ActivityLink") %>'></asp:Label>
</ItemTemplate>
you have to use GridView RowDataBound Event for that
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
System.Data.DataRowView dr = (System.Data.DataRowView)e.Row.DataItem;
if (Convert.ToBoolean(dr["columnName"].ToString()))
{
LinkButton LinkButton = (LinkButton)e.Row.Findcontrol("LinkButton");
LinkButton.Visible = false;
}
}
}

Categories