Attaching a click event onto an image within a grid view - c#

I am having trouble attaching a click event onto an image that I have stored within a grid view. Basically it is a delete button that will allow the user to delete a specific row depending on where the button is. I have the code in c# ready for it, however, I cannot seem to attach a click event to it.
This is the markup code of the button
<asp:TemplateField HeaderText="Remove" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:ImageButton ID="imgbDeleteP" runat="server" BORDER="0" CausesValidation="false" ImageUrl="~/img/Del.png" Height="25px" ImageAlign="Middle"
onClick ="gv_Quals_RowCommand" CommandArgument="<%#Container.DataItemIndex%>" CommandName="Remove" />
</ItemTemplate>
onClick ="gv_Quals_RowCommand"
Here is the code in c# for the click event
protected void gv_Quals_RowCommand(object sender, GridViewCommandEventArgs e)
{
if ((e.CommandName == "Remove"))
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = gv_Quals.Rows[index];
DataTable dtCurrentTable = (DataTable)Session["CurrentTable"];
dtCurrentTable.Rows[index].Delete();
if ((dtCurrentTable.Rows.Count < 0))
{
}
else if ((row.Cells[0].Text != "*New*"))
{
int appId = 5000;
//int appId = 1;
string insProg = ("delete from projectunitassignment where UnitId =" + int.Parse(row.Cells[0].Text));
SqlCommand cmd = new SqlCommand(insProg, conn);
cmd.Connection.Close();
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
RebindCat(appId);
}
}
}
This is the compilation error that I keep getting
CS0123: No overload for 'gv_Quals_RowCommand' matches delegate 'ImageClickEventHandler'
I cannot set the click event through the properties as it is stored within the grid view so I cannot access it through there. Also the click event does not run as I have tested with debugging

The problem is with GridViewCommandEventArgs should be just EventArgs
public void imgbDeleteP_Click(object sender, EventArgs e)
Edit:
I see that in your code you use the Command Argument, so if you want to use that you should see this post
Basically use onCommand instead of onClick or cast the sender to button to get the command argument, something like:
var argument = ((ImageButton)sender).CommandArgument;

Did you try to associate the click event for that grid during page load ?

I think that is because of GridViewCommandEventArgs which commonly used for RowCommand , change it to EventArgs, so that event should be something like this:
protected void gv_Quals_RowCommand(object sender, EventArgs e)
{
ImageButton btn = (ImageButton)sender;
string cmName= btn.CommandName;
string cmArgument= btn.CommandArgument;
if ((cmName == "Remove"))
{
.....
}
}
or to get row index:
GridViewRow gvRow = (GridViewRow)(sender as Control).Parent.Parent;
int index = gvRow.RowIndex;
The first parent is the GridView Cell and the second parent of the GridView Cell is the GridView Row.

Related

EventArgs VS GridViewRowEventArgs

I am trying to access the button click event from my asp.net gridview. If I leave my syntax like so
protected void Remove(Object sender, GridViewRowEventArgs e)
{
}
Their is no compile error but I get a debug error. of
No overload for '' matches delegate 'System.EventHandler'
Well if I change my syntax to this
protected void Remove(Object sender, EventArgs e)
{
var command = ((Button)sender).CommandArgument;
if (command.CommandName == "Remove")
{
DataGridItem gr = (DataGridItem)command.NamingContainer;
string abcd = gr.Cells[0].Text;
}
}
I get multiple compile errorrs of:
'string' does not contain a definition for 'CommandName' and no extension method 'CommandName' accepting a first argument of type 'string'
could be found (are you missing a using directive or an assembly reference?)
'string' does not contain a definition for 'NamingContainer' and no extension method 'NamingContainer' accepting a first argument of type 'string'
could be found (are you missing a using directive or an assembly reference?)
What I want to do is from the button press event in my grid view access the value and run a stored procedure.
And here is the aspx markup
<asp:GridView ID="gvwEditDashboard" runat="server" AutoGenerateColumns="False" ShowFooter="true" CssClass="DataGrids"
Width="500px" HorizontalAlign="Center" GridLines="Both" >
<Columns>
<ItemTemplate>
<asp:LinkButton ID = "btnDelete" runat = "server" CssClass="ButtonLink" Text = "[Delete]" OnClick = "Remove" />
</ItemTemplate>
</Columns>
</asp:GridView>
Firstly, understand that GridViewRowEventArgs is meant for events: RowCreated and RowDataBound. These events are not a button click event.
Secondly, when the LinkButton is clicked, there are possibly two events raised: LinkButton.Click and GridView.RowCommand.
My advice is to use/handle the RowCommand event of GridView.
There are many techniques to get the data of the Row where the button was clicked inside this event.
Specifically to your situation, declare the LinkButton as :
<ItemTemplate>
<asp:LinkButton ID = "btnDelete" runat = "server"
CssClass="ButtonLink" Text = "[Delete]" OnClick = "Remove"
CommandArgument="<%# Container.DataItemIndex %>" />
</ItemTemplate>
Notice the CommandArgument property of LinkButton.
And the RowCommand event. Notice that the second param is GridViewCommandEventArgs
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
// The RowIndex of the Row where LinkButton was clicked
int rowIndex = Convert.ToInt32(e.CommandArgument);
// Get the GridView Row
GridViewRow row = GridView1.Rows[rowIndex];
// Read the Column values
// e.g. for BoundFields use row.Cells[]
string Column_1_Value = row.Cells[0].Text;
// for Columns defined using <itemTemplate> etc...
// row.FindControl("<Control_ID>")
string firstName = (row.FindControl("txtFirstName") as TextBox).Text;
}
Alternative to LinkButton, you can use ButtonFields as well. Check the row command event at this link. The MSDN sample explains nicely on reading rows data.
protected void Remove(Object sender, EventArgs e)
{
var command = ((Button)sender).CommandArgument;
if (command.CommandName == "Remove")
{
DataGridItem gr = (DataGridItem)command.NamingContainer;
string abcd = gr.Cells[0].Text;
}
}
The hazards of var. CommandArgument is of type string on a button. You're getting that error because string has no CommandName or NamingContainer property.
Try the following:
protected void Remove(Object sender, CommandEventArgs e)
{
if (e.CommandName == "Remove")
{
DataGridItem gr = e.NamingContainer;
string abcd = gr.Cells[0].Text;
}
}

Gridview on Linkbutton click, Pass complete GridRow information to the next page? What are best ways to do this?

I have Gridview that has 6 other BoundField Columns and one Linkbutton column.
I want to pass all the Row information to the next page when users click on LinkButton.
What are the best ways to do this?
If we pass it as QueryString, it is going to be Too long.
Thanks
You can use the LinkButton Column itself to your advantage.
The idea is to send the RowIndex of the GridViewRow in PostBackUrl property of LinkButton as a QueryString Parameter.
Use the Container.DataItemIndex which represents the Index of the Row.
At the Next/Destination page , get the RowIndex from QueryString to get the GridViewRow and then read the Column values.
Step 1.) The markup corresponding to LinkButton should be as below:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkDetails" runat="server" Text="Send Details"
PostBackUrl='<%# "~/NextPage.aspx?RowIndex=" +
Container.DataItemIndex %>'>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Step 2.) In the Page Load event of NextPage.aspx, get first the GridViewRow where LinkButton was clicked and then read the row values
Note that using the PostBackUrl property in essence makes a cross page postback and therefore you can use the property Page.PreviousPage
protected void Page_Load(object sender, EventArgs e)
{
if (this.Page.PreviousPage != null)
{
int rowIndex = int.Parse(Request.QueryString["RowIndex"]);
GridView GridView1 = (GridView)this.Page.PreviousPage.FindControl("GridView1");
GridViewRow row = GridView1.Rows[rowIndex];
//Since you use Bound Fields, use row.Cells[] to read values
String Column_One_Value = row.Cells[0].Text;
String Column_Two_Value = row.Cells[1].Text;
}
}
Too long is subjective, anyways, if you don't want to use QueryString you can use Session Variables, Session vars are kept across the web site
protected void gvUsers_PageIndexChanging(object sender, EventArgs e)
{
Session["TheSelectedRow"] = ((Control)sender).Parent as GridViewRow;
// Your code to redirect
}
or you can wrap them in Properties, to work better and avoid casting every time in different lines and spelling mistakes
public GridViewRow TheSelectedRow
{
get { return Session["TheSelectedRow"] == null ? null : Session["TheSelectedRow"] as GridViewRow; }
set { Session["TheSelectedRow"] = value; }
}
and then in your click event this
protected void gvUsers_PageIndexChanging(object sender, EventArgs e)
{
TheSelectedRow = ((Control)sender).Parent as GridViewRow;
// Your code to redirect
}

how to get the column index of the gridview

I have two image buttons in the GridView used for selection. They populate the textboxes. What I need is when i click imagebutton "Edit" it should populate the textboxes from the gridview and when the imagebutton "Delete" is pressed it does the same and disbale the textboxes too. The point is am not getting a logic of how to get the column indexes programmatically.
help me out with the condition.
the issue is just with the c# code. Here is the snippet which i have tried:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
var row = GridView1.SelectedRow;
if (condition)
{
_PropertyTitle.Text = row.Cells[1].Text;
_Address.Text = row.Cells[2].Text;
}
else
{
_PropertyTitle.Text = row.Cells[1].Text;
_PropertyTitle.Enabled = false;
_Address.Text = row.Cells[2].Text;
_Address.Enabled = false;
}
}
}
It is not very clear from question that what you are trying to achieve.But what i got is you want to write specify both image button click separately.
for that you have to use the RowCommand event.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
}
In this row command event according to CommandName (of button) you can manage the code for two buttons
Refer this link for Rowcommand event row command
One more link

The GridView 'GridView1' fired event RowDeleting which wasn't handled , but there is an event

ı have been traying to create dynamic control panel using webusercontrol , delegate,and ADO.
Even ı have write the delegate for deleting and editing ı faced with "The GridView 'GridView1' fired event RowDeleting which wasn't handled."problem . Can anybody help me pls
here is my codes
protected void Page_Load(object sender, EventArgs e)
{
GridView1.DataSource = this.DataSource;
GridView1.DataBind();
GridView1.DataKeyNames = new string[] { this.DataKeyNames };
}
public object DataSource { get; set; }
public string DataKeyNames { get; set; }
public event GridHander RowDeleting;
public event GridHander RowSawing;
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
GridViewRow gvr = ((LinkButton)e.CommandSource).Parent.Parent as GridViewRow;
int rowIndex = gvr.RowIndex;
object id = GridView1.DataKeys[rowIndex].Value;
switch (e.CommandName)
{
case "Edit":
GridView1.EditIndex = rowIndex;
break;
case "Delete":
if (RowDeleting != null)
{
GridEventArgs args = new GridEventArgs()
{
row=gvr,
id=id,
rowIndex=rowIndex
};
RowDeleting.Invoke(e.CommandSource, args);
}
break;
case"Save":
if (RowSawing != null)
{
GridEventArgs args = new GridEventArgs()
{
row = gvr,
id = id,
rowIndex = rowIndex
};
RowSawing.Invoke(e.CommandSource, args);
}
GridView1.EditIndex = -1;
break;
case "Cancel":
GridView1.EditIndex = -1;
break;
default:
break;
}
}
}
//My webform
ublic partial class CategoryControlPanel : System.Web.UI.Page
{
CategoryResposite _categoryResposite=new CategoryResposite();
protected void Page_Load(object sender, EventArgs e)
{
ControlPanel.DataSource = _categoryResposite.ListCategories();
ControlPanel.RowDeleting += ControlPanel_RowDeleting;
ControlPanel.RowSawing += ControlPanel_RowSawing;
}
void ControlPanel_RowSawing(object sender, GridEventArgs e)
{
throw new NotImplementedException();
}
void ControlPanel_RowDeleting(object sender, GridEventArgs e)
{
_categoryResposite.DeleteCategories(Convert.ToInt32(e.id));
}
You are trying with a command name of Delete for your delete button. So the gridview creates a row deleting event automatically....
You need to change the command argument from Delete to something else like Delete_Product or whatever you want...
The code that you have posted is incomplete (missing the aspx file code), from your description of the problem it sounds as though you have not assigned the RowDeleting event to GridView1.
Inside the opening gridview tag in the aspx file add the assignment as follows:
<asp:gridview ID="..." runat="server" ... OnRowDeleting="<name of event handler>" ...>
If the event handler ControlPanel_RowDeleting is designed to handle a delete from gridview action then insert this as the event handler name. Ensure that you re-bind the gridview after delete so that the changes are shown on postback.
protected void ControlPanel_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
// cancel the automatic delete action
e.Cancel = true;
// do the delete
_categoryResposite.DeleteCategories(Convert.ToInt32(e.id));
// complete delete action
GridView1.DataBind();
}
One of the good things about GridView is that it provides a built-in CommandField Buttons which allows us to perform certain actions like editing, updating,deleting and selecting of GridView data.
To add those command fields mentioned in the GridView you can follow these few steps below:
1. Switch to Design View
2. Right Click on the GridView and Select --> Show Smart Tag --> Add New Columns
3. On the List Select CommandField
4. Check Delete and Edit/Update options then OK
As you can see the Edit and Delete CommandField are automatically added in the last column of GridView. Now we can start to write our codes for editing and updating the information in the GridView.
In-order to perform Edit and Update in GridView we need to use three events ( GridView_RowEditing, GridView_RowCancelingEdit , GridView_RowUpdating). For those who do not know on how to generate Events in GridView you can follow these steps below:
Switch to Design View in Visual Studio Designer
Click on the GridView
Navigate to the GridView Property Pane and then SWITCH to Event Properties
From there you would be able to find the list of events including those three events mentioned above
Double Click on that to generate the Event handler for you
Try adding protected to the method signatures.

accessing data of a GridView on button click

I am having a gridview with some columns and a template field column that contains a button and I want to call a procedure on button click, however I want to pass a value of a column to the procedure but I am getting an error, here is the action listener of the button: (column name in the gridview is team_ID)
error: Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.
error line: int team_ID = Convert.ToInt32(Eval("team_ID"));
protected void Button1_Click(object sender, EventArgs e)
{
string connStr = ConfigurationManager.ConnectionStrings["MyDbConn"].ToString();
SqlConnection conn = new SqlConnection(connStr);
SqlCommand cmd = new SqlCommand("join_team", conn);
cmd.CommandType = CommandType.StoredProcedure;
int team_ID = Convert.ToInt32(Eval("team_ID"));
string email = Session["email"].ToString();
cmd.Parameters.Add(new SqlParameter("#team_ID", team_ID));
cmd.Parameters.Add(new SqlParameter("#myemail", email));
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
First, to handle a button what was clicked in an TemplateField, you'll want to subscribe to the RowCommand method:
<asp:GridView runat="server" ID="gv" OnRowCommand="yourMethod">
You can have multiple buttons in your grid and surmise which caused the click with the CommandName property. The code below shows this, as well as how to get the row of the button that was clicked, and retrieve other controls from that row so you can get their values.
<asp:TemplateField>
<ItemTemplate>
<asp:Button CommandName="yourButtonName" runat="server" />
Code Behind
protected void yourMethod(object sender, GridViewCommandEventArgs e) {
if (e.CommandName == "yourButtonName") {
GridViewRow row = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
TextBox someTextBox = row.FindControl("tb") as TextBox;
string textValue = someTextBox.Text;
}
}

Categories