Is there some way to pass the unique client id to codebehind? I have a imagebutton in a gridview and I wish to do something like this:
<asp:ImageButton ID="imbView" runat="server" ToolTip="View details" ImageUrl="~/css/images/View.png" CommandName="wView" CommandArgument='#<%=imbView.ClientID%>' />
On debugging though I see that my CommandArgument is #<%=imbView.ClientID%>..
To specify: I want to pass something that uniquely identifies generated elements (and I thought that the ClientID would be a good way to identify it).
Huh ?
Assuming you have
<asp:ImageButton ID="imbView" runat="server" ToolTip="View details" ImageUrl="~/css/images/View.png" CommandName="wView" OnCommand="aaa" />
then -
protected void aaa(object sender, CommandEventArgs e)
{
var a= (sender as Control).ClientID;
}
Here is how you retrieve CommandArgument inside RowCommand event.
You can also use e.CommandSource as ImageButton inside RowCommand event.
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False"
OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField HeaderText="Detail">
<ItemTemplate>
<asp:ImageButton ID="imbView" runat="server"
ToolTip="View details" ImageUrl="~/css/images/View.png"
CommandName="wView"
CommandArgument='<%# Eval("Id") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Name" DataField="Name">
</asp:BoundField>
</Columns>
</asp:GridView>
Code Behind
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = new List<Item>
{
new Item {Id = 1, Name = "John"},
new Item {Id = 2, Name = "Eric"},
};
GridView1.DataBind();
}
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "wView")
{
var imageButton = e.CommandSource as ImageButton;
string clientId = imageButton.ClientID;
int id = Convert.ToInt32(e.CommandArgument);
}
}
Related
Error on RowUpdating >> GridView 'GView' fired the RowUpdating event, which was not handled.
I put the RowEditing and I can enter to update the data, but when I put public void GView_UpdateItem(int id) {} it returns the error saying GridView 'GView' triggered the RowUpdating event, which was not handled.
<asp:GridView runat="server" ID="GView" CellPadding="4" ForeColor="#333333" GridLines="None" OnRowEditing="GView_RowEditing" UpdateMethod="GView_UpdateItem">
<AlternatingRowStyle BackColor="White"></AlternatingRowStyle>
<Columns>
<asp:CommandField ShowEditButton="True"></asp:CommandField>
<asp:CommandField ShowDeleteButton="True"></asp:CommandField>
</Columns>
C# CODE
protected void Page_Load(object sender, EventArgs e)
{
}
public static List<Contato> contatos = new List<Contato>();
public void btnCad(object sender, EventArgs e)
{
Contato contato = new Contato();
contato.Id = contatos.Count;
contato.Nome = this.txtNome.Text;
contato.Idade = this.txtIdade.Text;
contato.Telefone = this.txtTelefone.Text;
contato.Genero = this.txtGenero.Text;
contato.DataCadastro = this.txtDataCad.Text;
contatos.Add(contato);
GView.DataSource = contatos;
GView.DataBind();
}
public void GView_UpdateItem(int id)
{
VoxTraining.Models.Contato item = contatos.Find(cont => cont.Id == id);
if (item == null)
{
ModelState.AddModelError("", String.Format("O item com id {0} não foi encontrado", id));
return;
}
TryUpdateModel(item);
if (ModelState.IsValid)
{
}
}
protected void GView_RowEditing(object sender, GridViewEditEventArgs e)
{
return ;
}
Ok, a few things.
Yes, we can do this without a database. We have have to persist our "list of names".
Dump the delete and edit buttons for the GV - they not worth the trouble - they don't help you.
So, we have the edit area, and the grid.
So, we have this markup:
<div id="myedit" runat="server" style="width:30%;padding:35px;display:none">
<div cssclass="form-group">
<label for="exampleInputEmail1">Nome</label>
<asp:TextBox CssClass="form-control" runat="server" ID="txtNome"></asp:TextBox>
</div>
<div cssclass="form-group">
<label for="exampleInputPassword1">Idade</label>
<asp:TextBox CssClass="form-control" runat="server" ID="txtIdade"></asp:TextBox>
</div>
<div cssclass="form-group">
<label for="exampleInputPassword1">Telefone</label>
<asp:TextBox CssClass="form-control" runat="server" ID="txtTelefone"></asp:TextBox>
</div>
<asp:Label runat="server" AssociatedControlID="txtGenero" ><b>Genero</b></asp:Label><br />
<asp:DropDownList CssClass="form-group" checked="" ID="txtGenero" runat="server" OnSelectedIndexChanged="btnCad">
<asp:ListItem Text="Masculino" />
<asp:ListItem Text="Feminino" />
</asp:DropDownList>
<div cssclass="form-group">
<label for="exampleInputPassword1">Data de Cadastro</label>
<asp:TextBox CssClass="form-control" runat="server" TextMode="Date" ID="txtDataCad"></asp:TextBox>
</div>
<br />
<asp:Button runat="server" ID="IDbtnCad" CssClass="btn" Text="Save" OnClick="btnCad" />
<asp:Button runat="server" ID="btnCancel" CssClass="btn" Text="Cancel" OnClick="btnCancel_Click"
style="margin-left:20px" />
<asp:Button runat="server" ID="btnDelete" CssClass="btn" Text="Delete" OnClick="btnCancel_Click"
style="margin-left:30px" />
</div>
<div id="MyGrid" runat="server">
<asp:Button ID="cmdNew" runat="server" Text="+Add new" CssClass="btn" OnClick="cmdNew_Click"/>
<asp:GridView runat="server" ID="GView" CellPadding="4" ForeColor="#333333" cssclass="table" Width="40%"
ShowHeaderWhenEmpty="true" >
<Columns>
<asp:TemplateField HeaderText="Edit" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn" OnClick="cmdEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White"></HeaderStyle>
</asp:GridView>
</div>
And code to load is this:
List<Contato> MyNames = new List<Contato>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewState["MyNames"] = MyNames;
GView.DataSource = MyNames;
GView.DataBind();
}
else
MyNames = ViewState["MyNames"] as List<Contato>;
}
Note how we save the list of names.
So, we now have this:
so, add new button is thus this:
protected void cmdNew_Click(object sender, EventArgs e)
{
// add new
Contato OneName = new Contato();
MyNames.Add(OneName);
MyEdit(MyNames.Count - 1);
}
And my edit is this:
void MyEdit(int RowIndex)
{
Contato OneName = MyNames[RowIndex];
txtNome.Text = OneName.Nome;
txtIdade.Text = OneName.Idade;
txtTelefone.Text = OneName.Telefone;
txtGenero.Text = OneName.Genero;
txtDataCad.Text = OneName.DataCadastro;
ViewState["RowIndex"] = RowIndex;
// show editor, hide grid
myedit.Style.Add("Display", "nomral");
MyGrid.Style.Add("display", "none");
}
so, we hit add, and we now have this:
We hit save button, this code
protected void btnCad(object sender, EventArgs e)
{
int RowIndex = (int)ViewState["RowIndex"];
Contato OneName = MyNames[RowIndex];
OneName.Nome = this.txtNome.Text;
OneName.Idade = this.txtIdade.Text;
OneName.Telefone = this.txtTelefone.Text;
OneName.Genero = this.txtGenero.Text;
OneName.DataCadastro = txtDataCad.Text;
ViewState["MyNames"] = MyNames;
myedit.Style.Add("Display", "none");
MyGrid.Style.Add("display", "normal");
GView.DataSource = MyNames;
GView.DataBind();
}
And we now have this:
We can use add again, and now this:
the edit row button - plane jane asp.net button click.
Code is this:
protected void cmdEdit_Click(object sender, EventArgs e)
{
Button btnEdit = sender as Button;
GridViewRow gRow = btnEdit.NamingContainer as GridViewRow;
MyEdit(gRow.RowIndex);
}
So, hitting edit button, goes back to the editor.
Say like this:
Cancel button - does nothing (no save, return to grid).
Say this:
protected void btnCancel_Click(object sender, EventArgs e)
{
myedit.Style.Add("Display", "none");
MyGrid.Style.Add("display", "normal");
}
And the delete button - that would just remove the current row index item from the list.
eg:
protected void cmdDel_Click(object sender, EventArgs e)
{
myedit.Style.Add("Display", "none");
MyGrid.Style.Add("display", "normal");
int RowIndex = (int)ViewState["RowIndex"];
MyNames.RemoveAt(RowIndex);
GView.DataSource = MyNames;
GView.DataBind();
}
I use RadGrid EditForm with UserControl like this sample Telerik Sample
<telerik:RadGrid ID="personGrid" runat="server" AutoGenerateColumns="False" OnEditCommand="personGrid_EditCommand" OnUpdateCommand="personGrid_UpdateCommand">
<MasterTableView DataKeyNames="ID" CommandItemDisplay="Top">
<EditFormSettings UserControlName="PersonItemsUC.ascx" EditFormType="WebUserControl">
</EditFormSettings>
<Columns>
<telerik:GridBoundColumn UniqueName="ID" Display="false" HeaderText="ID" DataField="ID">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="Name" HeaderText="Name" DataField="Name">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="Family" HeaderText="Family" DataField="Family">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="Age" HeaderText="Age" DataField="Age">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="MobileNo" HeaderText="MobileNo" DataField="MobileNo">
</telerik:GridBoundColumn>
<telerik:GridEditCommandColumn EditText="Update" UniqueName="EditCommandColumn">
</telerik:GridEditCommandColumn>
<telerik:GridButtonColumn UniqueName="DeleteColumn" Text="Delete" CommandName="Delete">
</telerik:GridButtonColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
and I have UserControl like this (have Person Info data)
I have method in My Usercontrol (GetDataFromControls)
public Person GetDataFromControls()
{
var sKey = typeof(Person).FullName + "Keys";
var p = new Person();
p.ID = Convert.ToInt32(SessionManager.Instance[sKey]); // ID store in Session with personGrid_EditCommand method
p.Name = txtName.Text;
p.Family = txtFamily.Text;
p.Age = Convert.ToInt32(txtAge.Text);
p.MobileNo = txtMobileNo.Text;
return p;
}
can get data from textboxes and other controls and set to Person instanse
OK now I want to update data so use this method in my page.aspx
protected void personGrid_UpdateCommand(object sender, GridCommandEventArgs e)
{
var userControl = e.Item.FindControl(GridEditFormItem.EditFormUserControlID) as PersonItemsUC;
if (userControl != null)
{
var p = userControl.GetDataFromControls(); //HERE
_personBusiness.Update(p);
}
}
first I found my usercontrol in UpdateCommand method and then call GetDataFromControls method but except ID that get from Session other data lost !!! all textboxes is empty
How can i call GetDataFromControls() method with valid data ?
Another solution that came to my mind saving GetDataFromControls to Session by this property
public Person CurrentEntity
{
get
{
var key = typeof(Person).FullName;
return SessionManager.Instance[key] as Person;
}
set
{
var key = typeof(Person).FullName;
SessionManager.Instance.Add(key, value);
}
}
and then call CurrentEntity instead of GetDataFromControls()
protected void personGrid_UpdateCommand(object sender, GridCommandEventArgs e)
{
var userControl = e.Item.FindControl(GridEditFormItem.EditFormUserControlID) as PersonItemsUC;
if (userControl != null)
{
var p = userControl.CurrentEntity; //HERE
_personBusiness.Update(p);
}
}
but I dont know when fill CurrentEntity in which event into my UserControl ?
CurrentEntity = GetDataFromControls(); // When assign method to CurrentEntity in My UserControl ???
Can anyone suggest good solution for calling GetDataFromControls from UserControl in Page.aspx without lost data ???
Please try with the below code snippet.
ASPX
<body>
<form id="form1" runat="server">
<div>
<telerik:RadScriptManager ID="RadScriptManager1" EnablePageMethods="true" runat="server">
</telerik:RadScriptManager>
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
</telerik:RadAjaxManager>
<telerik:RadGrid ID="RadGrid1" runat="server" AutoGenerateColumns="false" OnNeedDataSource="RadGrid1_NeedDataSource"
AllowMultiRowEdit="true" OnUpdateCommand="RadGrid1_UpdateCommand">
<PagerStyle AlwaysVisible="true" />
<MasterTableView DataKeyNames="ID" CommandItemDisplay="Top">
<Columns>
<telerik:GridBoundColumn DataField="ID" UniqueName="ID" HeaderText="ID">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="Name" UniqueName="Name" HeaderText="Name">
</telerik:GridBoundColumn>
<telerik:GridEditCommandColumn></telerik:GridEditCommandColumn>
</Columns>
<EditFormSettings UserControlName="WebUserControl1.ascx" EditFormType="WebUserControl">
<EditColumn UniqueName="EditCommandColumn1">
</EditColumn>
</EditFormSettings>
</MasterTableView>
</telerik:RadGrid>
</div>
</form>
</body>
ASPX.CS
public partial class Forum : System.Web.UI.Page
{
protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
List<Employee> list = new List<Employee>();
list.Add(new Employee() { ID = 1, Name = "Name1" });
list.Add(new Employee() { ID = 2, Name = "Name2" });
list.Add(new Employee() { ID = 3, Name = "Name3" });
list.Add(new Employee() { ID = 4, Name = "Name4" });
list.Add(new Employee() { ID = 5, Name = "Name5" });
RadGrid1.DataSource = list;
}
protected void RadGrid1_UpdateCommand(object sender, GridCommandEventArgs e)
{
GridEditableItem editedItem = e.Item as GridEditableItem;
UserControl userControl = (UserControl)e.Item.FindControl(GridEditFormItem.EditFormUserControlID);
string strName = (userControl.FindControl("TextBox1") as TextBox).Text; //Get usercontrol data
string strName1 = (userControl as WebUserControl1).GetDataFromControls(); //Call the usercontrol Method
//Perform your operation here
}
}
ASCX
<%# Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl1.ascx.cs" Inherits="WebUserControl1" %>
<%# Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
your Usercontrol......
<br />
<asp:Label ID="Label1" runat="server"></asp:Label>
<br />
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("Name") %>'></asp:TextBox>
<br />
<asp:Button ID="btnUpdate" Text="Update" runat="server" CommandName="Update"></asp:Button>
ASCX.CS
public partial class WebUserControl1 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public string GetDataFromControls()
{
return TextBox1.Text;
}
}
Let me know if any concern.
I have a gridview. The gridview has a textbox multiline that keeps an text. After that I have a column with imagebutton named approved, and one named not approved. I want to force the user before click approved or not approved to read the text inside the multiline box. How can I achieve this programmatically? I know I should create a Rowdatabound Event, but what I should do with the code? I am using c# ASP.NET web application.
I know you can track the scroll bar of the browser using javascript but I've personally never come across similar functionality for a text box. I would suggest trying a slightly different approach, why don't you add an extra column to you grid view which has a check box control for - I've read and accepted the agreement. And the Approve button will only be enabledd when the checkbox is checked, here's an example:
ASPX:
<div>
<asp:ScriptManager ID="sm" runat="server" />
<asp:UpdatePanel ID="updatePanel" runat="server">
<ContentTemplate>
<asp:GridView ID="grid" runat="server" AutoGenerateColumns="false" OnRowDataBound="grid_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox TextMode="MultiLine" runat="server" ID="txtAgreement" Text='<%# Eval("Agreement") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
I have read and accepted the agreement
<asp:CheckBox ID="chkAgreement" AutoPostBack="true" runat="server" OnCheckedChanged="CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnAccept" runat="server" Text="Accept" OnClick="Accept" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</div>
Code behind:
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var items = new List<License> { new License { Agreement = "Agreement 1" }, new License { Agreement = "Agreement 2" } };
grid.DataSource = items;
grid.DataBind();
}
}
protected void Accept(object sender, EventArgs e)
{
}
protected void grid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
(e.Row.FindControl("btnAccept") as Button).Enabled = false;
}
protected void CheckedChanged(object sender, EventArgs e)
{
var chkAgreement = sender as CheckBox;
Button btnAccept = null;
if (chkAgreement != null)
{
var row = chkAgreement.Parent.Parent as GridViewRow;
btnAccept = row.FindControl("btnAccept") as Button;
if (btnAccept != null)
if (chkAgreement.Checked)
btnAccept.Enabled = true;
else
btnAccept.Enabled = false;
}
}
}
public class License
{
public string Agreement { get; set; }
}
<telerik:RadGrid ID="RGStyleGuideRestrictions" runat="server" DataSourceID="SqlDataSource1"
OnItemCommand="RGStyleGuideRestrictions_ItemCommand"
<MasterTableView DataSourceID="SqlDataSource1" DataKeyNames="TerritoryReportGroup">
<Columns>
<telerik:GridTemplateColumn UniqueName="TemplateColumn">
<ItemTemplate>
<asp:ImageButton ID="imgBtn1" runat = "server"/>
<asp:ImageButton ID="imgBtn2" runat = "server"/>
</ItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
In CODE-BEHIND:-
protected void RGStyleGuideRestrictions_ItemCommand(object source, GridCommandEventArgs e)
{
ImageButton imgBtn1 = e.item.FindControl("imgBtn1") as ImageButton;
ImageButton imgBtn2 = e.item.FindControl("imgBtn2") as ImageButton;
}
QUESTION:- Now, click of any of the ImageButton fires the ItemCommand event. I want to find out or fetch the ID of that ImageButton(1 or 2) in codebehind, which fired the ItemCommand.
Please suggest what to do for that. I am clue less.
Have you tried applying CommandNames to your imagebuttons?
<asp:ImageButton ID="imgBtn1" runat = "server" CommandName="imgAction1"/>
<asp:ImageButton ID="imgBtn2" runat = "server" CommandName="imgAction2"/>
protected void RGStyleGuideRestrictions_ItemCommand(object source, GridCommandEventArgs e)
{
switch(e.CommandName)
{
case "imgAction1": // do stuff here
break;
case "imgAction2": // do some other stuff here
break;
}
}
The source object is the one that fired the command. Just cast the source to the image button and check whether is the button1 or button2.
protected void RGStyleGuideRestrictions_ItemCommand(object source, GridCommandEventArgs e)
{
ImageButton fired = source as ImageButton;
if(fired!=null && fired.Id=="imgBtn1")
{
//imgBtn1 fired the command
}
else
{
// and so on...
}
ImageButton imgBtn1 = e.item.FindControl("imgBtn1") as ImageButton;
ImageButton imgBtn2 = e.item.FindControl("imgBtn2") as ImageButton;
}
UPDATE
Since code above didn't work, try this approach:
<telerik:GridTemplateColumn UniqueName="TemplateColumn">
<ItemTemplate>
<asp:ImageButton CommandArgument="btn1" ID="imgBtn1" runat = "server"/>
<asp:ImageButton CommandArgument="btn2" ID="imgBtn2" runat = "server"/>
</ItemTemplate>
</telerik:GridTemplateColumn>
protected void RGStyleGuideRestrictions_ItemCommand(object source, GridCommandEventArgs e)
{
if(e.CommandArgument=="btn1")
{
//imgBtn1 fired the command
}
else if(e.CommandArgument=="btn2")
{
//imgBtn2 fired the command
}
ImageButton imgBtn1 = e.item.FindControl("imgBtn1") as ImageButton;
ImageButton imgBtn2 = e.item.FindControl("imgBtn2") as ImageButton;
}
Linking documentation to GridCommandEventArgs
I wrote a method that deletes rows from my an asp.net Gridview when the delete button is clicked and another method for when the edit button is clicked.
Both Edit and Delete buttons are part of the built in gridview controls.
However when I press these buttons (edit/delete)and exception is thrown.
Unable to cast object of type 'System.Web.UI.WebControls.GridView' to type 'System.Web.UI.WebControls.Button'. which is pointing at the line
Button btn = (Button)sender;
The problem here is that this line is not related to either of the edit or delete methods. It is related to the asp button in another column, and for that reason I am lost. How can I resolve this issue? What is causing both the OnRowDeleting and OnRowEditing conflict with the showResponses method?
Here is the aspx
<asp:GridView runat="server" ID="gvShowQuestionnaires" HeaderStyle-CssClass="table_header" CssClass="view" AlternatingRowStyle-CssClass="alt" AlternatingRowStyle-BackColor="#f3f4f8" AutoGenerateColumns="False"
DataKeyNames='QuestionnaireID' OnRowDeleting="gvShowQuestionnaires_RowDeleting" OnRowEditing="gvShowQuestionnaires_RowEdit" FooterStyle-CssClass="view_table_footer" OnRowCommand="showResponses">
<Columns>
<asp:BoundField DataField="QuestionnaireID" HeaderText="ID" HeaderStyle-Width="80px" ItemStyle-CssClass="bo"></asp:BoundField>
<asp:BoundField DataField="QuestionnaireName" HeaderText="Questionnaire Name" />
<asp:TemplateField HeaderText="Results" HeaderStyle-Width="150px">
<ItemTemplate>
<asp:Button runat="server" ID="button1" CommandArgument='<%# Eval("QuestionnaireID") %>' OnClick="showResponses" text="Results"/>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField HeaderText="Options" ShowDeleteButton="True" ShowEditButton="true" EditText="Edit"></asp:CommandField>
</Columns>
</asp:GridView>
And here is the code behind:
protected void gvShowQuestionnaires_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int questionnaireID = (int)gvShowQuestionnaires.DataKeys[Convert.ToInt32(e.RowIndex)].Value;
GetData.DeleteQuestionnaire(questionnaireID);
gvShowQuestionnaires.DataSource = DT;
gvShowQuestionnaires.DataBind();
}
protected void gvShowQuestionnaires_RowEdit(object sender, GridViewEditEventArgs e)
{
string id = gvShowQuestionnaires.Rows[e.NewEditIndex].Cells[0].Text;
Session["qID"] = id;
Response.Redirect("~/members/edit_questionnaire.aspx");
}
protected void showResponses(object sender, EventArgs e)
{
Button btn = (Button)sender;
string id = btn.CommandArgument.ToString();
Session["qID"] = id;
Response.Redirect("~/members/questionnaire_responses.aspx");
}
Any help would much appreciated.
It seems reasonably clear to me. Here:
<asp:GridView runat="server" ... OnRowCommand="showResponses">
you bind the RowCommand event to showResponses. And here, in showResponses, you assume that the sender is a button:
protected void showResponses(object sender, EventArgs e)
{
Button btn = (Button)sender;
string id = btn.CommandArgument.ToString();
Session["qID"] = id;
Response.Redirect("~/members/questionnaire_responses.aspx");
}
The sender isn't a button - it's the grid view. If you want the command argument, you should use GridViewCommandEventArgs.CommandArgument.
protected void showResponses(object sender, GridViewCommandEventArgs e)
{
Session["qID"] = e.CommandArgument;
Response.Redirect("~/members/questionnaire_responses.aspx");
}
Add a CommandName attribute to your button1 in the GridView.
<asp:Button runat="server" ID="button1" CommandName="Button1" CommandArgument='<%# Eval("QuestionnaireID") %>' OnClick="showResponses" text="Results"/>
Then in showResponses do this...
protected void showResponses(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Button1") {
Session["qID"] = e.CommandArgument;
Response.Redirect("~/members/questionnaire_responses.aspx");
}
}
var btnSender = (Button)e.CommandSource;