Updating GridView row on button click - asp.net

I have a GridView which contains a Link Button inside a Template Field. The code is shown below:
<asp:GridView ID="gv1" runat="server" AutoGenerateColumns="False"
DataSourceID="SqlDataSource1" onrowediting="gv1_RowEditing"
onrowcommand="gv1_RowCommand">
<Columns>
<asp:BoundField DataField="inDetailsId" HeaderText="inDetailsId"
SortExpression="inDetailsId" />
<asp:BoundField DataField="inUserId" HeaderText="inUserId"
SortExpression="inUserId" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnk1" runat="server" Text='<%# Eval("attDate")%>' CommandName="Edit"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="attstatus" HeaderText="attstatus"
SortExpression="attstatus" />
<asp:BoundField DataField="inAttendanceStatusId"
HeaderText="inAttendanceStatusId" SortExpression="inAttendanceStatusId" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:LearnConnectionString %>"
SelectCommand="SELECT * FROM [attendance]"></asp:SqlDataSource>
<asp:Button ID="Button1" runat="server" Text="Button" />
The code-behind is below:
protected void gv1_RowCommand(object sender, GridViewCommandEventArgs e)
{
gv1.EditIndex = 1;
}
On clicking the Link Button, I am setting GridView Edit Index to 1 to make the row editable.
Now I want to save the updated row. On Click of another button on the Web Page, I want to save the updated changes and change the row edit mode to non-editable mode.

The best way to do this is using the specifics events, this way:
protected void gridview1_RowEditing(object sender, GridViewEditEventArgs e)
{
gridview1.EditIndex = e.NewEditIndex;
BindGrid();
}
protected void gridview1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
gridview1.EditIndex = -1;
BindGrid();
}
To save use the event RowUpdating:
protected void gridview1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = gridview1.Rows[e.RowIndex];
int id = Convert.ToInt32(gridview1.DataKeys[e.RowIndex].Value);
string name = ((DropDownList)(row.Cells[2].Controls[1])).SelectedValue;
//call save method of your business layer
gridview1.EditIndex = -1;
BindGrid();
}
Remember to declare the event in the gridview markup.

Related

Gridview.row.count show zero whenever button is click

i have a gridview ,whenever user will click on row of gridview view ,
record will be populated in the textbox ,but i am getting error as
index was out of range. must be non-negative and less than the size of
the collection
also i check gridview.row.count is showing zero.
please help below is my code
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" ShowHeader="false" AllowPaging="false" AllowSorting="false" ToolTip="Click Here To Edit"
Style="table-layout: fixed;" OnRowDataBound="GridView1_RowDataBound"
CssClass="mGrid" PagerStyle-CssClass="pgr" DataKeyNames="AcheadID"
AlternatingRowStyle-CssClass="alt" Width="100%" Height="100%" >
<AlternatingRowStyle CssClass="alt" />
<Columns>
<asp:TemplateField ItemStyle-Width="40px">
<ItemTemplate>
<%#Container.DataItemIndex+1 %>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Account Head ID" DataField="AcheadID" HeaderStyle-HorizontalAlign="Left" Visible="false" />
<asp:TemplateField HeaderText="Account Head" HeaderStyle-HorizontalAlign="Left" ItemStyle-Width="400px">
<ItemTemplate>
<asp:Label ID="lblac_head" runat="server" Text='<%# Bind("ac_head") %>'></asp:Label>
<asp:HiddenField ID="hndacheadID" runat="server" Value='<%# Bind("AcheadID") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="btnTest" runat="server" OnClick="GridView1_OnClick" style="display:none;" />
my codebehind as
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GetAccountHead();
}
}
protected void GridView1_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HiddenField hndac_headid = (HiddenField)e.Row.FindControl("hndac_headid");
if (hndac_headid.Value != "0")
{
e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='#d3d3d3'");
e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor=''");
e.Row.Attributes.Add("style", "cursor:pointer;");
//e.Row.Attributes.Add("onclick", "location='patron_detail.aspx?id=" + e.Row.Cells[0].Text + "'");
e.Row.Attributes["OnClick"] = Page.ClientScript.GetPostBackClientHyperlink(btnTest, e.Row.RowIndex.ToString());
}
}
}
protected void GridView1_OnClick(object sender, EventArgs e)
{
Button buttonSender = sender as Button;
int index;
GridViewRow row = null;
if (int.TryParse(Request.Params.Get("__EVENTARGUMENT"), out index))
{
row = GridView1.Rows[index];
Label ac_head = (Label)GridView1.Rows[index].FindControl("lblac_head");
}
Index out of range issue happens because Request.Params.Get("__EVENTARGUMENT") doesn't works for Button ( and addiionally ImageButton ) controls.
The Button controls and ImageButton controls does not call the __doPostBack function. Because of this, the _EVENTARGUMENT ( and _EVENTTARGET as well ) will always be empty.
However, other controls such as CheckBoxes, DropDownLists, LinkButtons uses javascript function __doPostBack to trigger a postback.
Try using a LinkButton
As a second check( can be ignored ), just make sure Data is binded to GridView properly like check the IsPostback conditions etc...
Check your GridView, it has an Id GridView2 but you always referencer GridView1.

GridView Template Column hiddenfield value is always 0 while visibility false

I have GridView with Template Column.Inside the template column i have asp:hiddenfield. I am binding the value using Eval() method.When i am trying to access the value of hiddenfi not accesible while visibility false
ASPX
<asp:TemplateField HeaderText="Select" Visible="false">
<ItemTemplate>
<asp:HiddenField ID="hdnMasterId" runat="server"
Value='<%# DataBinder.Eval(Container.DataItem, "Master_Id") %>' />
<asp:CheckBox ID="chkDelete" runat="server" />
</ItemTemplate>
<ItemStyle Width="4%" HorizontalAlign="Center"></ItemStyle>
<HeaderStyle HorizontalAlign="Center" />
</asp:TemplateField>
CODE BEHIND
protected void gdvList_RowCommand(object sender, GridViewCommandEventArgs e)
{
int intIndex = Convert.ToInt32(e.CommandArgument);
GridViewRow row = gdvList.Rows[intIndex];
HiddenField hdn = (HiddenField)row.FindControl("hdnMasterId");
}
If you set visibility="false" on a column it won't generate any html, thus wont have the hidden control. You need to put the hiddenfield elsewhere or hide the column with css/style instead.
You could try as:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
string strValue = ((HiddenField)GridView1.SelectedRow.Cells[cellindex].FindControl("HiddenFieldID")).Value;
}

How can i call a code behind function when user clicks a gridview row?

I have a gridview in an aspx page with c# code behind.
Is there a way how i can run a code behind function when the user clicks anywhere on a row? For now, i use the select button. But then the user has to click on that button. And i want to user to be able to click anywhere on a row to show it's details in another gridview that is located next to the main gridview.
Some ideas here on how to do this?
Thanks!
try this
<asp:GridView runat="server" ID="GridView1" DataKeyNames="ID" AutoGenerateColumns="False"
Font-Names="Tahoma" Font-Size="Small" OnSelectedIndexChanged="GridView1_SelectedIndexChanged"
OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Row">
<ItemTemplate>
<%# Container.DataItemIndex+1 %>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="FirstName" HeaderText="First Name" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:CommandField ShowSelectButton="true" ButtonType="Link" Visible="false" SelectText="Enroll" />
</Columns>
</asp:GridView>
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = Enumerable.Range(1, 10).Select(a => new
{
ID = a,
FirstName = String.Format("First {0}", a),
LastName = String.Format("Last{0}", a)
});
GridView1.DataBind();
}
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
//Bind other grid
Response.Write(GridView1.SelectedIndex+1);
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//add css to GridViewrow based on rowState
e.Row.CssClass = e.Row.RowState.ToString();
//Add onclick attribute to select row.
e.Row.Attributes.Add("onclick", String.Format("javascript:__doPostBack('GridView1','Select${0}')", e.Row.RowIndex));
}
}

Fetching the id from the first column of GridView

I have a Grid in which I am showing some records in each row. Here's how it is:
Now, my problem is that when I press the view button, I want to fetch the ID from the first column in a session variable so that I can display the same ID on the next page.
For the ItemTemplate of EditButton, I am using this code:
<ItemTemplate>
<asp:LinkButton ID="EditBtn" CssClass="btn green" CommandName="edit" ToolTip="Edit" Text="Edit" runat="server" />
</ItemTemplate>
You could try passing it as command argument:
<ItemTemplate>
<asp:LinkButton
ID="EditBtn"
CssClass="btn green"
CommandName="edit"
CommandArgument='<%# Eval("FirstColumnId") %>'
OnCommand="EditCommand"
ToolTip="Edit"
Text="Edit"
runat="server" />
</ItemTemplate>
and in the code behind:
protected void EditCommand(object sender, GridViewCommandEventArgs e)
{
var id = e.CommandArgument;
// TODO: do something with the id
}
Try this. No changes are required at your aspx
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
Session["UserID"] = ((Label)GridView1.Rows[e.NewEditIndex].FindControl("lb1")).Text.Trim();
}
Other method (Using DataKeyNames - Preferred)
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
Session["UserID"] = GridView1.DataKeys[e.NewEditIndex].Value.ToString();
}

ModalPopupExtender inside a GridView ItemTemplate

How do I use a GridView TemplateField containing a LinkButton that is to display the modal on click? I have rows of data that I want to update the details of when clicking the 'Edit' LinkButton in that row. There is a bunch of data I need to load via codebehind just before the Modal displays.
I was trying the following, but I can't do Modal1.Show() in the event handler because it's in a TemplateField:
<ItemTemplate>
<asp:Button runat="server" ID="HiddenForModal" style="display: none" />
<ajaxToolkit:ModalPopupExtender ID="Modal1" runat="server" TargetControlID="HiddenForModal" PopupControlID="pnlModal" />
<asp:LinkButton ID="btnEdit" runat="server" Text="Edit" onclick="btnEdit_Click" />
<asp:LinkButton ID="btnDelete" runat="server" Text="Delete"></asp:LinkButton>
</ItemTemplate>
Thanks,
Mark
The key is knowing which row in the GridView was the LinkButton that was clicked. You can do this several ways but the way I implemented it is to capture it in the RowCommand event. Then you can access the ModalPopupExtender in the clicked row via FindControl(..).
Page:
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="Button1" runat="server" style="Display:none;" Text="Button" />
<cc1:ModalPopupExtender ID="ModalPopupExtender1" PopupControlID="Popup1" TargetControlID="Button1" BackgroundCssClass="modalBackground" runat="server" />
<asp:LinkButton ID="LinkButton1" CommandName="Popup" runat="server">Popup</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Codebehind:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton LinkButton1 = (LinkButton)e.Row.FindControl("LinkButton1");
LinkButton1.CommandArgument = e.Row.RowIndex.ToString();
}
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Popup" && e.CommandArgument != null)
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
ModalPopupExtender modalPopupExtender1 = (ModalPopupExtender)GridView1.Rows[rowIndex].FindControl("ModalPopupExtender1");
modalPopupExtender1.Show();
//Perform any specific processing.
Label1.Text = string.Format("Row # {0}", rowIndex);
}
}
Additionally, because you are opening the modal on a postback anyways you don't actually need the ModalPopupExtender (or the hidden button) in the ItemTemplate. You can move that out and put it on the page (by your popup div) and can simply call the Show() method.
Page:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" CommandName="Popup" runat="server">Popup</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Codebehind:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Popup" && e.CommandArgument != null)
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
ModalPopupExtender1.Show();
//Perform any specific processing
Label1.Text = string.Format("<Br>Row # {0}", rowIndex);
}
}
Thanks, good luck!

Resources