GridViewRowCommand keep fire - c#

by right my label1.text will be display by each clicks, however my label was fire during page load, and this is not what i want, so any idea can perform fire event per clicks?
gridview property
asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" OnRowDataBound="abcde"
link button that inside gridview
asp:LinkButton ID="lnkname" runat="server" Text='<%#Eval("movieTitle") %>' Width=500 CommandName="cmdLink">
code behind for link button
protected void abcde(object sender, GridViewRowEventArgs e)
{
Label1.Text = ((LinkButton)e.Row.FindControl("lnkname")).Text;
}

Problem is that whenever any click event occur in Gridview that time GridviewRowCommand will be fire..you just check that when you want to fire this event.its means during paging event also fire this event..thats y just check it out using [CommandName] like this
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowcommand.aspx
string namec = e.CommandName.ToString();
if (namec == "cmdLink")
{
//put your code
}

It sounds like you bind the gridview on page load event. Every time you bind the gridview, the onbound event will be fired:
protected void abcde(object sender, GridViewRowEventArgs e)
You can avoid that by checking postback in pageload before gridview databind:
if (!IsPostBack)
{
//Gridview databind
}

Change the Command Name of LinkButton to
CommandName="Select"
and use GridView1_SelectIndexChanged event
First Get the Select Row
GridViewRow gvr = new GridView1.SelectedRow;
and FindControl of the row

Related

LinkButton.Click event not firing when dynamically attached in GridView row databound

I have a asp:GridView inside of an asp:UpdatePanel, which has a column of asp:LinkButton controls.
On the row databound event, the LinkButton gets it's click event handler assigned.
I've tried every way I could find to wire up the click even and none of the events ever fire.
Am I doing something wrong?
aspx:
<asp:UpdatePanel ID="MainUpdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="lblTest" Text="test" runat="server" />
<asp:GridView ID="gvClientsArchive" runat="server" AllowSorting="true" DataSourceID="dsClients"
OnRowDataBound="gvClientsArchive_RowDataBound" SkinID="gvList"
AllowPaging="true" PageSize="25" Visible="false">
...
Code behind:
protected void gvClientsArchive_RowDataBound(object sender, GridViewRowEventArgs e)
{
...
int company_id = int.Parse(drvRow["company_id"].ToString());
LinkButton lnkRestore = (LinkButton)e.Row.FindControl("lnkRestore");
lnkRestore.Click += new System.EventHandler(this.doRestore);
Button handler code:
private void doRestore(object sender, EventArgs e)
{
lblTest.Text = "restore clicked";
}
I've also tried:
protected void gvClientsArchive_RowDataBound(object sender, GridViewRowEventArgs e)
{
...
LinkButton lnkRestore = (LinkButton)e.Row.FindControl("lnkRestore");
lnkRestore.Click += delegate
{
lblTest.Text = "restore clicked";
};
RowDataBound is inappropriate if you want to register event handlers. Use RowCreated:
protected void gvClientsArchive_RowCreated(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton lnkRestore = (LinkButton)e.Row.FindControl("lnkRestore");
lnkRestore.Click += new System.EventHandler(this.doRestore);
}
}
RowDataBound is triggered only if you Databind the grid not on every postback which is needed since all controls are disposed at the end of the page's lifecycle. It's also too late.
If you use TemplateFields it's easier to register the handler declaratively on the aspx.

RowDataBound not acting the way I expect

I have a Gridview with an ImageButton that should become visible for the selected row only. I'm doing this in the OnRowDataBound event, but it doesn't work.
protected void OnRowDataBoundMS(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
// some working code that handles the edit mode
}
else if (Gridview1.SelectedValue != null)
{
ImageButton ImgBut1 = e.Row.FindControl("ButtonUp") as ImageButton;
ImgBut1.Visible = true;
}
}
}
My gridview looks like this:
<asp:GridView runat="server"
ID="Gridview1"
DataSourceID="Milestones"
DataKeyNames="ID"
AutoGenerateColumns="false"
OnRowEditing="OnRowEditing"
OnRowDataBound="OnRowDataBoundMS"
OnSelectedIndexChanged="OnSelectedIndexChangedMS">
...
<asp:templatefield HeaderText="Order" ItemStyle-HorizontalAlign="center">
<ItemTemplate>
<asp:ImageButton ID="ButtonUp" runat="server" OnClick ="OrderUp" ImageUrl="img/up.png" Visible="false"/>
</ItemTemplate>
</asp:templatefield>
I spent the last 3 hours on this and I start to freak out. Any hints on this? Martin
The other alternative is to use the SelectedIndexChanged event if you are using the Select command option:
protected void OnSelectedIndexChangedMS(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
Control ctl = row.FindControl("ButtonUp");
ctl.Visible = (row.RowState & DataControlRowState.Selected) != 0;
}
}
Something like that; RowDataBound may fire before the selected index gets updated (not sure about that...).
You can detect the selected row in the RowDataBound event handler with the RowState property, the same way you detect the edit row:
if ((e.Row.RowState & DataControlRowState.Selected) != 0)
{
...
}
An alternative is to set the Visible property of the ImageButton in the markup, with a data-binding expression:
<asp:ImageButton runat="server" Visible='<%# ((Container as GridViewRow).RowState & DataControlRowState.Selected) != 0 %>' ... />
Note: make sure that you call GridView1.DataBind() in the SelectedIndexChanged event handler, in order to refresh the content of the GridView.
I guess the key comment is what Brian Mains said about the RowDataBound firing before the selected Index gets updated. I can't prove this to be generally right, but it seems so. Therefore all attempts, even following ConnersFan suggestions didn't worked out. I did what Brian suggested and used the SelectedIndexChanged event handler, but without looping through all rows. The solution is actually quite simple:
protected void OnSelectedIndexChangedMS(object sender, EventArgs e)
{
Gridview1.DataBind();
ImageButton ImgBut1 = Gridview1.SelectedRow.FindControl("ButtonUp") as ImageButton;
ImgBut1.Visible = true;
}

How to fire event of textbox with OnItemCommand of a repeater , without using LinkButton?

I have a repeater with a textbox inside , and I want to fire an event
when I move from one textbox to another textbox , with the OnItemCommand of
the repeater .
<asp:Repeater ID="RptrPeople" runat="server" OnItemDataBound="RptrPeople_ItemDataBound" OnItemCommand="RptrPeople_ItemCommand">
<ItemTemplate>
<asp:HiddenField ID="hf" runat="server" Value="<%# Eval(this.ValuedPerson) %>" />
<asp:TextBox ID="txtDescription" runat="server" IsRequired="false" Visible="true" AutoPostBack="true" />
</ItemTemplate>
</asp:Repeater>
I tried to use the OnTextChanged of the Textbox , but I can't get the item that fired the event this way .
Can anyone please advise on a good way to get the item that fires the event , after I moved from one textbox , using the OnItemCommand (for example , I entered 123 in Textbox #1 , and then moved to Textbox #2 ... then I want to fire the event that takes care of the Textbox that has the 123 value) ?
Thanks
I tried to use the OnTextChanged of the Textbox , but I can't get the
item that fired the event this way .
The sender argument is always the control that triggered the event:
protected void txtDescription_TextChanged(Object sender, EventArgs e)
{
TextBox txtDescription = (TextBox) sender;
}
So you should use this instead of OnItemCommand because there the sender is the repeater.
If you also need to get the reference of the HiddenField use following code:
protected void txtDescription_TextChanged(Object sender, EventArgs e)
{
TextBox txtDescription = (TextBox) sender;
var item = (RepeaterItem) txtDescription.NamingContainer;
HiddenField hf = (HiddenField) item.FindControl("hf");
}
The NamingContainer of any control in a RepeaterItem is always the RepeaterItem. As an aside, that's working similar for other web-databound controls like GridView or DataList.

Getting the Contents of a Gridview in Row Command

This is the code in UI
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btn" runat="server" CommandName="Edit" Text="AFE" />
</ItemTemplate>
</asp:TemplateField>
--</Columns>
I Want to Get the Details of All Fields in Text boxes in Same page when ever I click on the Button Edit. I Tried using :
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Edit")
{
GridViewRow Row = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
string text = Row.Cells[2].Text;
}
But I am getting "" in string text..
This is screenshot of my grid view
You can use the row index stored in command argument to find a row where Edit button is clicked.
Now you can find the TextBox in that row where cell index location is 2.
Then get the Text of your TextBox.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName == "Edit")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow clickedRow = CustomersGridView.Rows[index];
TextBox myTextBox = (TextBox)clickedRow.Cells[2].FindControl("TextBoxName");
string text = myTextBox.Text;
}
}
In ASPX page, you need to handle row command event like this:
<asp:gridview id="GridView1"
datasourceid="DataSource"
autogeneratecolumns="false"
onrowcommand="GridView1_RowCommand"
runat="server">
</asp:gridview>
You can access to GridViewRow using following code (note: the Button must be the control that has CommandName/CommandArgument):
var row = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
Then simply use FindControl method on found row to find your target control, for ex.:
var txtSomething = (TextBox)row.FindControl("txtSomething");
Also you can access to RowIndex using row.RowIndex.
I recommended avoid using row.Cells[INDEX].FindControl(), just row.FindControl works just fine, targeting specific cell isn't good, if you change the markup and add/remove some columns, (maybe) you need to update the INDEX too, so don't do that :)
You need to find the TextBox control in the cell and get the value from it.
string text = (TextBox)Row.FindControl["MyTextBoxId"].Text;

dynamically add a link button in gridview template field at run time together a label control

I have a gridview in my form. I am working with RowDataBound event to the grid. Now I have a template field inside columns of the gridview. A label has been taken inside template field. I want to add a link to this label on RowDataBound event at runtime, but .System.Web.UI.WebControls.LinkButton is showing instead of link button.
How do I add a link button with label text in the grid view?
Just add a linkbutton inside your templatefield
<asp:GridView runat="server" ID="gridView">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="lnkTest"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Then in your rowdatabound event you can find it and do whatever you want
void gridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Entity entity = e.Row.DataItem as Entity;
LinkButton lnkTest = e.Row.FindControl("lnkTest") as LinkButton;
lnkTest.CommandArgument = entity.ID.ToString();
lnkTest.Text = entity.Name;
}
}
You can then subscribe to gridview Command event and correct CommandArgument will be passed when clicking by linkbutton.
Hope this helps.

Categories