I am trying to show a button where IsPublished is true, it works but except for the first row in the grid. Why? I have been trying it for so long but it doesn't work at all
protected void gvNITs_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
//LinkButton lb = e.Row.FindControl("btnLinkDownload") as LinkButton;
//if (lb != null)
// ScriptManager.GetCurrent(this).RegisterPostBackControl(lb);
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton Lbtn_change = (LinkButton)e.Row.FindControl("Lbtn_change");
HiddenField hdnPublishNITDate = e.Row.FindControl("hdnPublishedNITdate") as HiddenField;
DateTime? dtPublishedNITDate = string.IsNullOrEmpty(hdnPublishNITDate.Value) == true ? null : (DateTime?)hdnPublishNITDate.Value.ToDate();
HiddenField hdnIsPublishedNIT = e.Row.FindControl("hdnIsPublishedNITs") as HiddenField;
bool IsPublished = hdnIsPublishedNIT.Value.ToBool();
GridView gv = (GridView)sender;
foreach (GridViewRow gvr in gv.Rows)
{
if (IsPublished == true)
{
Lbtn_change.Visible = true;
}
}
}
}
}
It does not work because you have a nested loop. The RowDataBound event is triggered when a row is being added to the GridView. But in the RowDataBound event you loop all the rows in the GridView foreach (GridViewRow gvr in gv.Rows)
If you check gv.Rows.Count you will find that it is 0 in the first row because it has not yet been added to the GridView.
But you do not need that loop anyway since you already have access to Lbtn_change. So set the Visible property without the loop.
Related
Everybody. I know there are lots of similar question but still I am asking for it because the earlier query doesn't meet my requirement. I have look for it, please don't mark it as duplicate. I am trying to change the row color of the Gridview where txt_Id.Text is equal to the Id of the Gridview row. Below is the code :
protected void lnkSelect_Click(object sender, EventArgs e)
{
LinkButton lnkbtn = sender as LinkButton;
GridViewRow gvrow = lnkbtn.NamingContainer as GridViewRow;
int Id = Convert.ToInt32(GridView4.DataKeys[gvrow.RowIndex].Value.ToString());
txt_Id.Text = Id.ToString();
foreach (GridViewRow row1 in GridView4.Rows)
{
if (txt_Id.Text != "")
{
if (row1.Cells[1].Text.Equals(txt_Id.Text))
{
row1.BackColor = System.Drawing.Color.Red;
row1.ForeColor = System.Drawing.Color.White;
}
}
}
I have two gridviews, one is on the main page and the other is modal. Both gridviews have one checkbox defined as asp:TemplateField.
What I want is: When I click one checkbox on the modal gridview, all the related checkboxes in the other gridview checked. The code is as follows:
protected void Secil_CheckedChanged(object sender, EventArgs e)
{
int selRowIndex = ((GridViewRow)(((CheckBox)sender).Parent.Parent)).RowIndex;
CheckBox cb = (CheckBox)GridIller.Rows[selRowIndex].FindControl("Secil");
if (cb.Checked)
{
string secili = HttpUtility.HtmlDecode(GridIller.Rows[selRowIndex].Cells[1].Text);
foreach (GridViewRow row in GridView1.Rows)
{
CheckBox cb1 = (CheckBox)row.FindControl("Sec");
if (HttpUtility.HtmlDecode(row.Cells[7].Text) == secili)
{
if (row.RowType == DataControlRowType.DataRow)
{
GridView1.EditIndex = -1;
cb1.Checked = true;
}
}
}
}
When I debug the program I see that cb1.checked=true; statement is executing but checkbox in the gridview remains unchecked.
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;
}
}
}
trying to pass parameter from a label in gridview, only the label text from the first row are passed.
not sure what is missing.
protected void GV1_OnRowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "edit")
{
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
Label lbl_taskID = (Label)row.FindControl("lbl_taskID");
Session["TaskID"] = lbl_taskID.Text;
Response.Redirect("~/tasks_edit.aspx");
}
}
}
}
You are breaking loop with Response.Redirect You need to put the do Response.Redirect out side loop to set all value, you also need to concatenate value of lbl_taskID all rows instead of over writting.
protected void GV1_OnRowCommand(object sender, GridViewCommandEventArgs e)
{
string taskIds = string.Empty;
if (e.CommandName == "edit")
{
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
Label lbl_taskID = (Label)row.FindControl("lbl_taskID");
if(Session["TaskID"] != null)
taskIds = Session["TaskID"].ToString();
Session["TaskID"] = taskIds + lbl_taskID.Text + ",";
}
}
Response.Redirect("~/tasks_edit.aspx");
}
}
If only the first row is used, then why you using foreach loop? You can simply find the control of the 0th row.
if (e.CommandName == "edit") //this makes sure that you have a row
{
Label lbl_taskID = (Label)GridView1.Rows[0].FindControl("lbl_taskID");
Session["TaskID"] = lbl_taskID.Text;
Response.Redirect("~/tasks_edit.aspx");
}
If you mean label text from currently editing column then, take the index of the editing column from the CommandArgument and get the label
if (e.CommandName == "edit") //this makes sure that you have a row
{
int index = Convert.ToInt32(e.CommandArgument); //currently editing row index
Label lbl_taskID = (Label)GridView1.Rows[index].FindControl("lbl_taskID");
Session["TaskID"] = lbl_taskID.Text;
Response.Redirect("~/tasks_edit.aspx");
}
How come you have lbl_taskID in every row? In your foreach loop your doing-
Label lbl_taskID = (Label)row.FindControl("lbl_taskID");
You are actually only taking the value of lbl_taskID present in your first row. The next rows will not have the same element again. Your coding is wrong. You will need to name your labels in each row with some thing like this- label0, label1,... then in your code you can do-
int i=0;
foreach(GridViewRow row in GridView1.Rows)
{
Label xyz = (Label)row.FindControl("Label"+i);
Session["TaskID"+i] =xyz.Text; //to have unique session variables
i++;
}
Response.Redirect("~/tasks_edit.aspx"); // you should redirect only when you come out of the loop
You are using a foreach loop, but you are using the loop to assign a single value to a single Session variable. So what do you expect?
However, i would assume that your last row is assigned not the first.
You need to put Response.Redirect("~/tasks_edit.aspx") outside of the loop since it will abort the current request. You might want to assign the row which is currently in edit-mode:
foreach (GridViewRow row in gridView1.Rows)
{
if (row.RowState == DataControlRowState.Edit)
{
Label lbl_taskID = (Label)row.FindControl("lbl_taskID");
Session["TaskID"] = lbl_taskID.Text;
break;
}
}
Response.Redirect("~/tasks_edit.aspx");
Side-note: you don't need to check the DataControlRowType since GridView.Rows only returns rows with DataControlRowType.DataRow anyway(unlike RowDataBound-event).
Edit: Instead of RowCommand i would use the click event of the LinkButton:
protected void EditLink_Clicked(Object sender, EventArgs e)
{
// get the LinkButton reference
LinkButton link = (LinkButton) sender;
// get the GridViewRow reference via NamingContainer
GridViewRow row = (GridViewRow) link.NamingContainer;
Label lbl_taskID = (Label) row.FindControl("lbl_taskID");
Session["TaskID"] = lbl_taskID.Text;
Response.Redirect("~/tasks_edit.aspx");
}
I have used the auto generated EDIT button from gridview wizard and it is working.
sorry for your time waste.
I am trying to find a DropDown element in the GridView_RowCommand but it says that GridViewCommandEventArgs does not contain a definituon for 'Row'. I need to do this in this event because i am evaluating a GridView Command. See failing code below
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Add")
{
DropDownList Myddl = null;
ClientClass client = new ClientClass();
Myddl = e.Row.FindControl("ddlClients") as DropDownList;
if (Myddl != null)
{
updated = client.InsertUpdateClient(ClientID,
int.Parse(e.CommandArgument.ToString()), departmentID);
}
else
{
Labels.Text = "There was an error updating this client";
}
}
}
Something like this:
GridViewRow row = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
This is assuming what's firing off the RowCommand is a LinkButton. Change that according.
In addition to the #Stephen,
if (e.CommandName == "Add")
{
DropDownList Myddl = null;
ClientClass client = new ClientClass();
//Use this if button type is linkbutton
GridViewRow row = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
//Use this if button type is Button
//GridViewRow row = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
Myddl = row.FindControl("ddlClients") as DropDownList;
if (Myddl != null)
{
updated = client.InsertUpdateClient(ClientID,
int.Parse(e.CommandArgument.ToString()), departmentID);
}
else
{
Labels.Text = "There was an error updating this client";
}
}