Gridview Rowcommand fires only once - Where is the error? - c#

My code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
BindDetails();
}
public void BindDetails()
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Name", typeof(string)));
dt.Columns.Add(new DataColumn("Designation", typeof(string)));
dt.Columns.Add(new DataColumn("Address", typeof(string)));
for (int i = 0; i < 10; i++)
{
DataRow dr = dt.NewRow();
if (i % 2 == 0)
{
dr["Name"] = "Ram";
dr["Designation"] = "Manager";
dr["Address"] = "Nerul";
}
else
{
dr["Name"] = "Shyam";
dr["Designation"] = "CEO";
dr["Address"] = "Vashi";
}
dt.Rows.Add(dr);
}
grdDetails.DataSource = dt;
grdDetails.DataBind();
}
protected void grdDetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Button btnEdit = (Button)e.Row.FindControl("btnEdit");
//btnEdit.Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference((Control)sender, "value$" + e.Row.RowIndex.ToString()));
e.Row.Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference((Control)sender, "value$" + e.Row.RowIndex.ToString()));
}
}
protected void grdDetails_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "value")
{
txtName.Text = grdDetails.Rows[Convert.ToInt32(e.CommandArgument)].Cells[0].Text;
txtDesignation.Text = grdDetails.Rows[Convert.ToInt32(e.CommandArgument)].Cells[1].Text;
txtAddress.Text = grdDetails.Rows[Convert.ToInt32(e.CommandArgument)].Cells[2].Text;
}
}
kindly give the solution.

If i remember correctly the AttributeCollection is not persisted in ViewState. Then you need to register the click event on every postback not only on databinding. Hence try to use RowCreated instead of RowDataBound.
protected void grdDetails_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Button btnEdit = (Button)e.Row.FindControl("btnEdit");
//btnEdit.Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference((Control)sender, "value$" + e.Row.RowIndex.ToString()));
e.Row.Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference((Control)sender, "value$" + e.Row.RowIndex.ToString()));
}
}

Related

Deleting a row from datatable and displaying the updated gridview

Adding data in datatable from dropdown and displaying it in gridview. Then I am deleting a row and maintaining the ViewState but after deleting one row and mapping my values again I get the earlier state of the table in the gridview with duplicated records.
Here's the code:
DataTable dt = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
//dt = new DataTable("tblTest");
//dt = ViewState["updatedtbl"] as DataTable;
DataColumn dc1 = new DataColumn();
dc1.DataType = typeof(String);
dc1.ColumnName = "A";
DataColumn dc2 = new DataColumn();
dc2.DataType = typeof(String);
dc2.ColumnName = "B";
dt.Columns.Add(dc1);
dt.Columns.Add(dc2);
//ViewState["dt"] = dt;
}
protected void Button2_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
if (Path.GetExtension(FileUpload1.FileName) == ".xlsx")
{
DataTable dt = new DataTable();
ExcelPackage package = new ExcelPackage(FileUpload1.FileContent);
dt = package.ToDataTable();
DropDownList1.Items.Clear();
for (int i = 0; i < dt.Columns.Count; i++)
{
DropDownList1.Items.Add(new ListItem(dt.Columns[i].ColumnName));
}
}
}
}
protected void Button3_Click(object sender, EventArgs e)
{
Session["A"] += DropDownList1.SelectedItem.Value + "|";
Session["B"] += DropDownList2.SelectedItem.Value + "|";
CreateTable();
}
public void CreateTable()
{
string[] sa = Session["A"].ToString().Split('|');
string[] sb = Session["B"].ToString().Split('|');
int recordnum = sa.Length;
for (int j = 0; j < recordnum - 1; j++)
{
DataRow dr = dt.NewRow();
dr["A"] = sa[j].ToString();
dr["B"] = sb[j].ToString();
dt.Rows.Add(dr);
}
ViewState["tbl"] = dt;
BindGrid();
}
protected void BindGrid()
{
GridView2.DataSource = dt;
GridView2.DataBind();
}
protected void GridView2_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
DataTable dx = ViewState["tbl"] as DataTable;
//DataTable dx = dt;
if (dx.Rows.Count > 0)
{
dx.Rows[e.RowIndex].Delete();
dx.AcceptChanges();
GridView2.DataSource = dx;
GridView2.DataBind();
ViewState["updatedtbl"] = dx;
}
else //To check which portion of code is being executed
{
Label1.Text = "Deleted";
Label2.Text = dx.Rows.Count.ToString();
}
}
In delete event you are reassigning the updated datatable to different viewstate with name updatedtbl. You should assign it to ViewState["tbl"].
if(dx.Rows.Count > 0)
{
dx.Rows[e.RowIndex].Delete();
dx.AcceptChanges();
GridView2.DataSource = dx;
GridView2.DataBind();
//ViewState["updatedtbl"] = dx; <<---- pay attention here
ViewState["tbl"] = dx; <<---- pay attention here
}

Gridview row in editing mode when I press "Insert" button? asp.net C#

I have a gridview and some control below the griview. I insert values from "control" and press "Insert" button then the values are inserted into the gridview row. Here is the gridview image when I insert values in control
and press the "Insert" button
and when I click on the "edit" button in griview the values of the selected edit row are displayed below the "controls" but when I update values in the control and click again "insert" then the row automatically edits the data, but I don't want this, I want that when I click on "insert" again that the row should not display in edit mode, here is the image
I want that when I click on "insert" button that the row values are replaced with new values.
Here is my aspx.cs code:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DataTable dt = new DataTable();
dt.Columns.Add("ID", System.Type.GetType("System.Int32"));
dt.Columns.Add("Column Name", System.Type.GetType("System.String"));
dt.Columns.Add("Data Type", System.Type.GetType("System.String"));
dt.Columns.Add("Allow Null", System.Type.GetType("System.Boolean"));
dt.Columns.Add("Primary Key", System.Type.GetType("System.Boolean"));
Session["MyDataTable"] = dt;
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
DataTable t = (DataTable)Session["MyDataTable"];
DataRow row1 = t.NewRow();
row1["ID"] = t.Rows.Count + 1;
row1["Column Name"] = TextBox1.Text;
row1["Data Type"] = DropDownList1.Text;
row1["Allow Null"] = Null.Checked == true ? "true" : "false";
row1["Primary Key"] = Primary.Checked == true ? "true" : "false";
t.Rows.Add(row1);
Session["MyDataTable"] = t;
GridView2.DataSource = t;
GridView2.DataBind();
TextBox1.Text = String.Empty;
DropDownList1.Text = "Select DataType";
}
protected void GridView2_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
DataTable t = (DataTable)Session["MyDataTable"];
t.Rows.RemoveAt(e.RowIndex);
GridView2.DataSource = t;
GridView2.DataBind();
}
protected void GridView2_RowEditing(object sender, GridViewEditEventArgs e)
{
DataTable t = (DataTable)Session["MyDataTable"];
//GridView2.EditIndex = e.NewEditIndex;
// TextBox1.Enabled = true;
//GridViewRow row = GridView2.Rows[e.NewEditIndex];
TextBox1.Text = GridView2.Rows[e.NewEditIndex].Cells[2].Text.ToString();
DropDownList1.Text = GridView2.Rows[e.NewEditIndex].Cells[3].Text.ToString();
GridView2.DataSource = t;
GridView2.DataBind();
}
protected void GridView2_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
DataTable t = (DataTable)Session["MyDataTable"];
GridView2.EditIndex = -1;
GridViewRow row = GridView2.Rows[e.RowIndex];
GridView2.DataSource = t;
GridView2.DataBind();
}
public void cancel(object sender, GridViewCancelEditEventArgs e)
{
DataTable t = (DataTable)Session["MyDataTable"];
GridView2.EditIndex = -1;
GridViewRow row = GridView2.Rows[e.RowIndex];
GridView2.DataSource = t;
GridView2.DataBind();
}

Dynamically added gridview's linkbutton not working

I have a gridview that has dynamically created columns.
Right now all the data is showing in its respective place but I am unable to get my link button to work. (Gridview disappears)
Here is my backend code, the gridview used is just an empty gridview
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
TemplateField tfield = new TemplateField();
tfield.HeaderText = "View";
GridView1.Columns.Add(tfield);
}
GridView1.DataBind();
}
string selectedID = null;
private void BindGrid(List<string> SelectedInfo)
{
DataTable dt = new DataTable();
//Dynamically adding columns and setting first column added as ID
selectedID = SelectedInfo[0];
for (int i = 0; i < SelectedInfo.Count; i++)
{
dt.Columns.Add(new DataColumn(SelectedInfo[i], typeof(string)));
}
List<string[]> InfoList = getInfoList(SelectedInfo);
for (int i = 0; i < InfoList.Count; i++)
{
dt.Rows.Add(InfoList[i]);
}
GridView1.DataSource = dt;
GridView1.DataBind();
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{ //Adding link button to first column
LinkButton lnkView = new LinkButton();
lnkView.ID = "lnkView";
lnkView.Text = "View";
lnkView.Click += ViewDetails;
lnkView.CommandArgument = (e.Row.DataItem as DataRowView).Row[selectedID].ToString();
e.Row.Cells[0].Controls.Add(lnkView);
}
}
protected void ViewDetails(object sender, EventArgs e)
{
//Popup the selected row ID
LinkButton lnkView = (sender as LinkButton);
GridViewRow row = (lnkView.NamingContainer as GridViewRow);
string id = lnkView.CommandArgument;
ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('Row ID" + id + "')", true);
}
protected void CheckBoxList2_SelectedIndexChanged(object sender, EventArgs e)
{
List<string> SelectedInfo = new List<string>();
for (int i = 0; i < CheckBoxList2.Items.Count; i++)
{
if (CheckBoxList2.Items[i].Selected)
{
SelectedInfo.Add(CheckBoxList2.Items[i].Text);
}
}
BindGrid(SelectedInfo);
}
If you need to create controls at runtime, you better use the RowCreated event:
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{ //Adding link button to first column
LinkButton lnkView = new LinkButton();
lnkView.ID = "lnkView";
lnkView.Text = "View";
lnkView.Click += ViewDetails;
lnkView.CommandArgument = (e.Row.DataItem as DataRowView).Row[selectedID].ToString();
e.Row.Cells[0].Controls.Add(lnkView);
}
}
Otherwise you have to bind your GridView on every postback inViewDetails the Page_Load event.
Anyway if your GridView disappears, it's just because you have to bind it again in the ViewDetails method.
I hope below code will help you.
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
TemplateField tfield = new TemplateField();
tfield.HeaderText = "View";
GridView1.Columns.Add(tfield);
}
this.BindGrid();
}
private void BindGrid()
{
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[2] { new DataColumn("Id", typeof(int)),
new DataColumn("Name", typeof(string)) });
dt.Rows.Add(1, "A");
dt.Rows.Add(2, "B");
GridView1.DataSource = dt;
GridView1.DataBind();
}
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton lnkView = new LinkButton();
lnkView.ID = "lnkView";
lnkView.Text = "View";
lnkView.Click += ViewDetails;
lnkView.CommandArgument = (e.Row.DataItem as DataRowView).Row["Id"].ToString();
e.Row.Cells[2].Controls.Add(lnkView);
}
}
protected void ViewDetails(object sender, EventArgs e)
{
LinkButton lnkView = (sender as LinkButton);
GridViewRow row = (lnkView.NamingContainer as GridViewRow);
string id = lnkView.CommandArgument;
ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('Id: " + id + "')", true);
}

how to delete from gridview without database "check to determine if the object is null before calling the method"

The ff are codes in my .cs file
private void BindGridview(int rowcount)
{
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new System.Data.DataColumn("Code", typeof(String)));
dt.Columns.Add(new System.Data.DataColumn("Course", typeof(String)));
dt.Columns.Add(new System.Data.DataColumn("Credit", typeof(String)));
if (ViewState["CurrentData"] != null)
{
for (int i = 0; i < rowcount + 1; i++)
{
dt = (DataTable)ViewState["CurrentData"];
if (dt.Rows.Count > 0)
{
dr = dt.NewRow();
dr[0] = dt.Rows[0][0].ToString();
}
}
dr = dt.NewRow();
dr[0] = this.cboCourseCode.Text;
dr[1] = this.txtCourseName.Text;
dr[2] = this.txtCredit.Text;
dt.Rows.Add(dr);
}
else
{
dr = dt.NewRow();
dr[0] = this.cboCourseCode.Text;
dr[1] = this.txtCourseName.Text;
dr[2] = this.txtCredit.Text;
dt.Rows.Add(dr);
}
// If ViewState has a data then use the value as the DataSource
if (ViewState["CurrentData"] != null)
{
GridView1.DataSource = (DataTable)ViewState["CurrentData"];
GridView1.DataBind();
}
else
{
// Bind GridView with the initial data assocaited in the DataTable
GridView1.DataSource = dt;
GridView1.DataBind();
}
// Store the DataTable in ViewState to retain the values
ViewState["CurrentData"] = dt;
}
protected void BindGrid()
{
GridView1.DataSource = ViewState["dt"] as DataTable;
GridView1.DataBind();
}
protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e)
{
int index = Convert.ToInt32(e.RowIndex);
DataTable dt = ViewState["dt"] as DataTable;
dt.Rows[e.RowIndex].Delete();
ViewState["dt"] = dt;
BindGrid();
}
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string Code = e.Row.Cells[0].Text;
foreach (Button button in e.Row.Cells[3].Controls.OfType<Button>())
{
if (button.CommandName == "Delete")
{
button.Attributes["onclick"] = "if(!confirm('Do you want to delete " + Code + "?')){ return false; };";
}
}
}
}
protected void cboCourseCode_SelectedIndexChanged(object sender, EventArgs e)
{
this.Populate_Course_Details();
}
protected void BtnAdd_Click(object sender, EventArgs e)
{
/* DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[3] { new DataColumn("Code"), new DataColumn("Course"), new DataColumn("Credit") });
dt.Rows.Add(this.cboCourseCode.Text, this.txtCourseName.Text, this.txtCredit.Text);
ViewState["dt"] = dt;
BindGrid();*/
if (ViewState["CurrentData"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentData"];
int count = dt.Rows.Count;
BindGridview(count);
}
else
{
BindGridview(1);
}
}
My aspx file also has this gridview
<asp:GridView ID="GridView1" CssClass = "Grid" runat="server" OnRowDeleting="OnRowDeleting" AutoGenerateColumns = "false" OnRowDataBound = "OnRowDataBound">
<Columns>
<asp:BoundField DataField="Code" HeaderText="Code" />
<asp:BoundField DataField="Course" HeaderText="Course" />
<asp:BoundField DataField="Credit" HeaderText="Credit" />
<asp:CommandField ShowDeleteButton="True" ButtonType="Button" />
</Columns>
</asp:GridView>
When I start to delete, I get this error:
check to determine if the object is null before calling the method
Error Reason
in OnRowDeleting function you are creating datatable and assigning viewstate["dt"],which doesn't have current data. that's why it shows Object is Null
Solution
Try This
First make one of the column as data key.consider i want to make "Code" column as datakey.
datakey will help to find specific row to delete
<asp:GridView ID="GridView1" CssClass = "Grid" runat="server" OnRowDeleting="OnRowDeleting" AutoGenerateColumns = "false" OnRowDataBound = "OnRowDataBound" DataKeyNames="Code">
After That in .cs code
create a datatable with currentdata
make "Code" column as primary key
find particular code(which you want to delete)using find()
then delete that row using delete() function
Reflect the deletion in viewsate["currentdata"]
then bind to gridview
protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e)
{
string code = GridView1.DataKeys[e.RowIndex].Value.ToString();
if (ViewState["CurrentData"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentData"];
dt.PrimaryKey = new DataColumn[] { dt.Columns["Code"] };
dt.Rows.Find(code).Delete();
ViewState["CurrentData"] = dt;
GridView1.DataSource = dt;
GridView1.DataBind();
}
}

search values from datatable (similer to like clause ) without using database

public partial class WebForm4 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!(IsPostBack))
{
Session["List"] = null ;
}
}
public static DataTable dt;
public static int i = 1;
// static int i = 1;
//static List<string> lst;
protected void btnAdd_Click(object sender, EventArgs e)
{
Session["List"] = dt;
dt = new DataTable();
DataRow dr = null;
// dt.Columns.Add(new DataColumn("RowNumber", typeof(int)));
dt.Columns.Add(new DataColumn("Column1", typeof(string)));
// dt.Columns.Add(new DataColumn("Column2", typeof(string)));
if (Session["List"] == null)
{
dr = dt.NewRow();
dr["Column1"] = txtAdd.Text;
dt.Rows.Add(dr);
// lst.Add(txtAdd.Text);
}
else if (Session["List"] != null)
{
dt = (DataTable)Session["List"];
dr = dt.NewRow();
dr["Column1"] = txtAdd.Text;
dt.Rows.Add(dr);
//lst = (List<string>)Session["List"];
//lst.Insert(i,txtAdd.Text);
//i++;
}
}
protected void btnNew_Click(object sender, EventArgs e)
{
List<string> lst = new List<string>();
foreach (DataRow row in dt.Rows)
{
foreach (DataColumn col in dt.Columns)
{
lst.Add(row[col].ToString());
}
}
for (int j = 0; j >= dt.Rows.Count; j++)
{
}
bool isfound = lst.Contains(txtSearch.Text);
Response.Write(Convert.ToString(isfound));
dlshow.DataSource = dt; // i want to bind only matching values to datalist
dlshow.DataBind();
}
}
i have two textboxes one to add and other is to search i want to bind only those matching
values matches with search textbox ( Like ' Like ' clause ) i am not using any data base
//just this will do
protected void btnAdd_Click(object sender, EventArgs e)
{
List <string > lst = (List<string >)Session["List"];
lst.Add(txtAdd.Text);
// Change the list in session with new list
Session["List"] = lst;
}
Here the logic is wrong like you r testing if the session["list"] is null then u want to do the operation but if session is null then lst would also be null
List <string > lst = (List<string >)Session["List"];
lst.Add(txtAdd.Text);
DataTable dt2 = dt.Select("Column1 Like '%" + txtSearch.Text + "%'").CopyToDataTable();
dlshow.DataSource = dt2; // i want to bind only matching values to datalist
dlshow.DataBind();

Categories