Row Data Bound in ASP.NET Grid View C# - c#

I have a grid view and need to bind IsActive field.But from the database it comes as 1 or 0.
Error shows System.InvalidCastException: 'Specified cast is not valid.'
Grid
<asp:BoundField DataField="IsActive" HeaderText="Status">
<ItemStyle Width="200px" />
</asp:BoundField>
Code
protected void grid1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (((int)DataBinder.Eval(e.Row.DataItem, "IsActive") == 1))
{
e.Row.Cells[12].Text = "Active";
}
else
{
e.Row.Cells[12].Text = "Inactive";
}
}
}

Try grabbing the underlying data item first and then checking for it.
protected void grid1_RowDataBound(object sender, GridViewRowEventArgs e)
{
DataRowView rowView = null;
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Retrieve the underlying data item
rowView = (DataRowView)e.Row.DataItem;
// Make sure we can parse and compare what we get.
if (int.TryParse(rowView["IsActive"].ToString(), out int isActive) && isActive == 1)
{
e.Row.Cells[12].Text = "Active";
}
else
{
e.Row.Cells[12].Text = "Inactive";
}
}
}

Related

Not able to access dynamically generated templated field controls

I am creating dynamic Template Fields for my gridview:
<asp:GridView ID="grdData" runat="server" DataKeyNames = "ID" AutoGenerateColumns="false" OnRowDataBound="grdData_RowDataBound">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="chkAll" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged" runat="server" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="editbtn" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
the code to add templateField is below:
private void BindGridView(DataTable dtData)
{
foreach (DataColumn item in dtData.Columns)
{
TemplateField tfield = new TemplateField();
tfield.HeaderText = item.ToString();
grdData.Columns.Add(tfield);
}
grdData.DataSource = dtData;
ViewState["dtDataTable"] = dtData;
grdData.DataBind();
}
and in row databound I am adding textbox and label to the templatefield:
protected void grdData_RowDataBound(object sender, GridViewRowEventArgs e)
{
DataTable dtData = (DataTable)ViewState["dtDataTable"];
if (e.Row.RowType == DataControlRowType.DataRow)
{
int i = 1;
foreach (DataColumn item in dtData.Columns )
{
TextBox txtBox = new TextBox();
txtBox.ID = "txt"+item.ToString();
txtBox.Text = (e.Row.DataItem as DataRowView).Row[item.ToString()].ToString();
txtBox.Visible = false;
e.Row.Cells[i].Controls.Add(txtBox);
Label lblBox = new Label();
lblBox.ID = "lbl" + item.ToString();
lblBox.Text = (e.Row.DataItem as DataRowView).Row[item.ToString()].ToString();
e.Row.Cells[i].Controls.Add(lblBox);
i++;
}
}
}
Everything is working good so far,The grid is getting created and the values are getting populated ,but when i am calling below method and try to access the gridview control ,its throwing object reference error:
protected void OnCheckedChanged(object sender, EventArgs e)
{
bool isUpdateVisible = false;
CheckBox chk = (sender as CheckBox);
if (chk.ID == "chkAll")
{
foreach (GridViewRow row in grdData.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
row.Cells[0].Controls.OfType<CheckBox>().FirstOrDefault().Checked = chk.Checked;
}
}
}
CheckBox chkAll = (grdData.HeaderRow.FindControl("chkAll") as CheckBox);
chkAll.Checked = true;
foreach (GridViewRow row in grdData.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
bool isChecked = row.Cells[0].Controls.OfType<CheckBox>().FirstOrDefault().Checked;
for (int i = 1; i < row.Cells.Count; i++)
{
Label test= row.FindControl("lblName") as Label;//this is coming null
Below code lines are throwing object reference error as they are not able to find control
row.Cells[i].Controls.OfType<Label>().FirstOrDefault().Visible = !isChecked;//this line throwing object reference error
if (row.Cells[i].Controls.OfType<TextBox>().ToList().Count > 0)
{
row.Cells[i].Controls.OfType<TextBox>().FirstOrDefault().Visible = isChecked;
}
if (row.Cells[i].Controls.OfType<DropDownList>().ToList().Count > 0)
{
row.Cells[i].Controls.OfType<DropDownList>().FirstOrDefault().Visible = isChecked;
}
if (isChecked && !isUpdateVisible)
{
isUpdateVisible = true;
}
if (!isChecked)
{
chkAll.Checked = false;
}
}
}
}
btnUpdate.Visible = isUpdateVisible;
}
Edit:
I tried reinistialising the controls in preinit event but still no luck:
protected void Page_PreInit(object sender, EventArgs e)
{
if (ViewState["gridData"] != null)
{
BindGridView((DataTable)ViewState["gridData"]);
}
}
What I am doing wrong?
I recreated the dynamic gridview Controls in OnRowCreated as this event gets called in every postback instead of onRowDataBound Event and it worked like charm.

Disable a row in gridview based on column name

I am using the below code to disable row in gridview where the column name is test. Everything works fine except for the first row. The color does not get applied to the first row. Where am I going wrong?I also want to hide a column based on column name.
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (Hidden4.Value == "Data Present")
{
foreach (GridViewRow item in GdvTestData.Rows)
{
int a = GetColumnIndexByName(item, "test");
int b = GetColumnIndexByName(item, "id");
if (e.Row.RowType == DataControlRowType.DataRow)
{
string test = e.Row.Cells[a].Text;
foreach (TableCell cell in e.Row.Cells)
{
if (test == "Y")
{
cell.BackColor = Color.Gray;
e.Row.Attributes.Add("onmouseover", "alert('This data is for testing');");
}
}
e.Row.Cells[b].Visible = false;
}
}
}
}
Maybe you are confusing data/business logic and UI.
RowDataBound event works per row so you don't need to loop gridview rows.
You are working on cell content but you have data bound to those. So:
ASPX
<asp:GridView runat="server" ID="gv" ...
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("Test") %>' />
</ItemTemplate>
</asp:TemplateField>
...
Code Behind
private void GrdBind()
{
// populate datatable
gv.DataSource = myDataTable;
gv.Databind();
}
And the databound event:
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (Hidden4.Value == "Data Present")
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRow row = ((DataRowView)e.Row.DataItem).Row;
string test = row.Field<String>("Test");
if (test== "Y")
{
e.Row.Cells[0].BackColor = Color.Gray; // set your index
e.Row.Attributes.Add("onmouseover", "alert('This data is for testing');");
}
}
}
}
You can do this. Although I don't understand what you mean by disabling a row.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//check if the row is a datarow
if (e.Row.RowType == DataControlRowType.DataRow)
{
//cast the dataitem back to a datarowview
DataRowView row = e.Row.DataItem as DataRowView;
//find the column value in the row, not the cell text
string test = row["columnName"].ToString();
//check the value and if so apply backcolor
if (test == "Y")
{
e.Row.BackColor = Color.Red;
//or hide the row (no need to do this in Databind or OnPreRender)
e.Row.Visible = false;
}
}
}

How to hide row in GridView if certain column is empty?

I have a GridView that displays some information about a job and one of the options in the GridView is to select a reason. If a reason isn't selected then I don't want to display that row in the GridView. How do I check if there is a value in the Reason column, and if its empty how do I hide that row?
private GridView BuildDebriefGridView()
{
GridView gv = new GridView();
gv.AutoGenerateColumns = false;
//gv.RowDataBound +=
gv.Columns.Add(new BoundField { HeaderText = "Job No", DataField = "JobNo" });
gv.Columns.Add(new BoundField { HeaderText = "Qty Rcvd", DataField = "QtyRcvd" });
gv.Columns.Add(new BoundField { HeaderText = "Reason", DataField = "Reason" });
gv.Columns.Add(new BoundField { HeaderText = "Comment", DataField = "Comment" });
gv.Attributes.Add("style", "width:100%");
return gv;
}
void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
JobPieceSerialNo item = e.Row.DataItem as JobPieceSerialNo;
if (item != null)
{
if (string.IsNullOrEmpty(item.Reason))
{
e.Row.Visible = false;
}
}
}
}
Try following;
private void gvTransportListResults_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.Cells["Reason"].Text == "")
e.Row.Visible = false;
}
Or if it is a checkbox
private void gvTransportListResults_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(((CheckBox)e.Row.FindControl("YourCheckboxID")).Checked == false)
e.Row.Visible = false;
}
Using GridView_RowDataBound event you can achieve this.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.Cells[ReasonCellNumber].Text == "Reason")
{
e.Row.Visible = false;
}
}
}

Get BoundField value in GridView RowDataBound event

I want to take LangId value in RowDataBound function. How to do this?
<asp:BoundField DataField="LangId" HeaderText="LangId" Visible="false" />
protected void grdList_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// need LangId
ImageButton imgBtn = (ImageButton)e.Row.FindControl("imgBtnDelete");
imgBtn.Visible = false;
}
}
There are a couple of ways to do it. Maybe more.
<asp:BoundField DataField="LangId" HeaderText="LangId" Visible="false" />
protected void grdList_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string langId = e.Row.Cells[columnIndex].Text; // one of the ways
string langId2 = DataBinder.Eval(e.Row.DataItem, "LangId").ToString(); // one of the other ways
}
}
You can get it by this:
string str = e.Row.Cells[CloumnIndexOfYourBoundField].Text;
ColumnIndexOfYourBoundField means if your column is first column than its index is 0 and if its second than its 1 and so on.
The data object is available as e.Row.DataItem at that time. You just need to cast it as the appropriate type.
var myItem = (MyType)e.Row.DataItem;
// myItem.LangId now available
.ASPX file:
<ItemTemplate>
<asp:ImageButton ID="imgEdit" runat="server" AlternateText="Edit"
CommandArgument='<%# Eval("LangId") %>' CommandName="DeleteLedger" ToolTip="Delete"
ImageUrl="~/App_Themes/DefaultClient/images/Delete.png" />
</ItemTemplate>
.CS file:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
DataRowView dataRow = ( DataRowView ) e.Item.DataItem;
string strLangId = dataRow["LangId"].ToString();
DataTable dtData1 =
objAccountTypeBAL.ChkLedgerRelation(Convert.ToInt64(strLangId ), objSession.BranchId);
if (dtData1.Rows.Count > 0)
{
ImageButton img = (ImageButton)item["Delete"].Controls[0];
img.Visible = false;
}
}
Using dynamic type you can access the fields in your record:
if (e.Row.RowType == DataControlRowType.DataRow)
{
dynamic data = e.Row.DataItem;
int LangId = data.LangId;
// do your code here
}
protected void GrdEmplistFromAtt_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[0].Attributes.Add("onmouseover", "MouseEvents(this, event)");
e.Row.Cells[0].Attributes.Add("onmouseout", "MouseEvents(this, event)");
}
if (e.Row.RowType == DataControlRowType.DataRow)
{
Label lbl_GrdCode = (Label)e.Row.FindControl("lblGrdCode");
}
}

How do I change the background color of a row in a GridView if a checkbox in the row is enabled?

I would like to change the background color of all the rows with value for "active" column unchecked in a GridView. I tried the following way but it doesn't work:
protected void GdvDetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
CheckBox chkItem = null;
foreach (GridViewRow grRow in GdvDetails.Rows)
{
if (grRow.RowType == DataControlRowType.DataRow)
{
chkItem = (CheckBox)grRow.Cells[6].FindControl("active");
if (chkItem.Checked )
{
grRow.BackColor = Color.Red;
}
}
}
}
The error message is "Object reference not set to an instance of an object."
Your code doesn't work because you need to do it on RowDataBund
protected void CustomersGridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
//Paste your code here.
}
}
And add a handler for RowDataBound as so:
<asp:gridview id="CustomersGridView"
allowpaging="true"
onrowdatabound="CustomersGridView_RowDataBound"
runat="server">
</asp:gridview>
You need to handle RowDataBound event instead of DataBound event, so put you in RowDataBound event as below:
In aspx page, after added the event the code will look like:
<asp:gridview id="GdvDetails"
onrowdatabound="GdvDetails_RowDataBound"
runat="server">
</asp:gridview>
In code behind(.cs):
protected void GdvDetails_RowDataBoundd(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
CheckBox chkItem = (CheckBox)e.Row.FindControl("active");
if (chkItem.Checked)
{
GdvDetails.SelectedRow.BackColor = Color.LightGray;
}
}
}
So this WORKS :)
protected void GdvDetails_DataBound(object sender, EventArgs e)
{
CheckBox chkItem = null;
foreach (GridViewRow grRow in GdvDetails.Rows)
{
if (grRow.RowType == DataControlRowType.DataRow)
{
chkItem = (CheckBox)grRow.Cells[6].FindControl("CkbActive");
bool bl = chkItem.Checked;
if (bl == false)
{
grRow.BackColor = Color.LightGray;
}
}
}
}
And the aspx file has
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID= "CkbActive" Checked ='<%# Bind ("active") %>' Enabled="false" runat="server"/>
</ItemTemplate>
</asp:TemplateField>
in the GridView GdvDetails.
i didn't use the code under onrowdatabound because its an event for each row and i thought it will iterate unnecessarily. And this works... just in case anyone else is fumbling like me?!! thx for all the help

Categories

Resources