PostBackTrigger on multiple LinkButtons in an update panel - c#

I have a search form in an updatePanel which retrieves a list of users in a grid in the same UpdatePanel. The name of each user is a commandLink. I want to make the commandLinks as PostBackTriggers.
But when I do it I get an error at the pageLoad time that the controlId does not exist and its true because the grid of users does not render at the load time but through an ajax call.
Any ideas on how can I make the multiple command buttons in a grid retrieved through ajax call as post back triggers?

When adding the items to the grid, within the ItemDataBound event handler, you should register the postback for each specific control (the static identifiers in your HTML declarations are essentially placeholders - not all things repeated in the grid can actually have the same ID). You do this using the ScriptManager.RegisterAsyncPostBackControl method:
The RegisterAsyncPostBackControl method enables you to register Web
server controls as triggers so that they perform an asynchronous
postback instead of a synchronous postback. When the
ChildrenAsTriggers property of an UpdatePanel control is set to true
(which is the default), postback controls inside the UpdatePanel
control are automatically registered as asynchronous postback
controls.
As stated above, using ChildrenAsTriggers is a possibility, too, but this is commonly set to false for more stringent management.

I have found the solution. Here is the code on asp
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="txtFirstName" runat="server"></asp:TextBox>
<asp:Button ID="btnSearch" runat="server" OnClick="btnSearch_Click" Text="Search" />
<asp:GridView ID="gvSearchResult" runat="server" OnRowCommand="gvSearchResult_RowCommand"
OnRowDataBound="gvSearchResult_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:LinkButton ID="lnkbtnDetail" runat="server" CommandArgument='<%# Bind("CNIC") %>' CommandName="Detail">
<asp:Label ID="lblName" Text='<%# Bind("Employee_Name") %>' runat="server</asp:Label>
</asp:LinkButton>
</ItemTemplate>
<ItemStyle HorizontalAlign="Left" VerticalAlign="Middle"Height="25px"Width="30%" />
</asp:TemplateField>
</Columns>
</asp:GridView>
Ihad to place OnRowDataBound="gvSearchResult_RowDataBound" on gridView and that function looks like below. So I had to register the iterative control in Scriptmanager as PostBackControl in RowDataBound event of GridView.
protected void gvSearchResult_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
if ((e.Row.RowType == DataControlRowType.DataRow))
{
LinkButton lnkbtnDetail = (LinkButton)e.Row.FindControl("lnkbtnDetail");
ScriptManager.GetCurrent(this).RegisterPostBackControl(lnkbtnDetail);
}
}
catch (Exception ex)
{
}
}

Related

Event in Update panel is not fired after rebinding control after Postback

I have a Gridview together with some LinkButton inside of an Update Panel. The click events are fired correctly, the way I expect them to work. BUT: After adding an additional Header Row to the grid in code behind, I need to rebind the Grid after each postback. Since then the click causes a postback, but the method is not executed.
<asp:UpdatePanel runat="server" ID="UpdatePanel2" UpdateMode="Always">
<ContentTemplate>
<asp:GridView ID="GridViewFollowUpMove" runat="server" AutoGenerateColumns ="false" OnRowDataBound="FollowUp_RowDataBound" OnDataBound="FollowUpMove_OnDataBound">
<Columns>
<asp:TemplateField HeaderText="Due date" ItemStyle-HorizontalAlign="left">
<ItemTemplate>
<asp:LinkButton ID="LB_DueDate" runat="server" OnClick="ActivateDueDate" CssClass="NoDeco" CommandArgument='<%# Bind("ISSUEID") %>'>
<asp:Label ID="LabelDueDate" runat="server" Text='<%# Bind("DueDate","{0:dd.MM.yyyy}") %>' Width="60px" Class="line"/></asp:LinkButton>
<asp:TextBox ID="TXTBX_DueDate" runat="server" Text='<%# Bind("DueDate") %>' Font-Size="11px" visible="false" OnTextChanged="TextChanged_DueDate" AutoPostBack="true"/>
</ItemTemplate>
</asp:TemplateField>
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
FillFollowUp();
}
FillFollowUp();
}
I solved this problem by moving the commands that create and customize the additional Header row to the OnRowCreated Event. As I read somewhere: When a postback occurs, the Gridview must be recreated on the server, and in this process ItemCreated is fired for each item, but ItemDataBound is not (since the control properties are pulled from ViewState).
So building these headers in DataBound is the wrong choice!

AsyncPostBackTrigger works only the first time

I have an update panel that includes a gridview.
This grid has a drop down list column.
Beta aspx code:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" EnablePartialRendering="false" UpdateMode="Conditional">
...
<asp:GridView ID="Gv_Queue" runat="server">
<Columns>
<asp:TemplateField HeaderText="H">
<ItemTemplate>
<asp:DropDownList ID="ddl_proprietà" runat="server" OnSelectedIndexChanged="ddl_proprietà_SelectedIndexChanged" AutoPostBack="true"/>
</ItemTemplate>
</Columns>
</asp:GridView
</asp:UpdatePanel>
I add the triggers of the DDL in the UpdatePanel by code:
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = dl.UniqueID; //dl is the Drop Down control
UpdatePanel1.Triggers.Add(trigger);
It works good at the fist selectedIndexChanged event... but the second time that the event is fired the trigger does not work correctly because a post back operation runs.
I already tried:
to change the AsyncPostBackTrigger to a PostBackTrigger but a missing
component exception is thrown.
change the updateMode in theUpdatePanel attribute to 'Always'.
Put another UpdatePanel in the ItemTemplate Column only for the
DropDown.
You have to re-create the trigger on every postback. You could add this code to the Load event of the DropDownList:
aspx:
<asp:TemplateField HeaderText="H">
<ItemTemplate>
<asp:DropDownList ID="ddl_proprietà" OnLoad="ddl_proprietà_OnLoad" runat="server" OnSelectedIndexChanged="ddl_proprietà_SelectedIndexChanged" AutoPostBack="true"/>
</ItemTemplate>
</asp:TemplateField>
codebehind:
protected void ddl_proprietà_OnLoad(object sender, EventArgs e)
{
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = ((Control)sender).UniqueID; // sender is the DropDown control
UpdatePanel1.Triggers.Add(trigger);
}
I found a solution to my own question.
You were all rights: I naively forgot that the trigger did not work after the first event just because it must be recreate.
Strangely even the recreation of the trigger in the on_Load even did not resolve the problem.
I did the trick with another update panel like this:
<asp:TemplateField HeaderText="H">
<ItemTemplate>
<asp:UpdatePanel runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:DropDownList ID="ddl_proprietà" runat="server" OnSelectedIndexChanged="ddl_proprietà_SelectedIndexChanged"
AutoPostBack="true"/>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddl_proprietà" />
</Triggers>
</asp:UpdatePanel>
</ItemTemplate>
</asp:TemplateField>
In my case the issue was because I had 2 controls on the page with the same Id. You may want to check this out if the previous responses did not resolve the issue.

Gridview OnRowDeleting event won't fire when EnableEventValidation = false

I'm using a gridview, there is no problem binding it and filling it with data from code-behind. But now I want to use the OnRowDeleting event so that I'm able to delete a row from my gridview.
When I press the delete button I got this error:
0x800a139e - JavaScript runtime error: Sys.WebForms.PageRequestManagerServerErrorException: Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
So I added EnableEventValidation = false, then when I pressed the delete button nothing happend at all. The event wasn't fired (checked with a breakpoint at GridView1_RowDeleting).
How can I make the event fire without any problems?
My gridview:
<asp:GridView ID="GridView1" runat="server" OnRowEditing="GridView1_RowEditing"
AllowSorting="True" AutoGenerateColumns="False" SkinID="gridviewGridlinesSkin"
OnRowUpdated="GridView1_RowUpdated" OnRowUpdating="GridView1_RowUpdating"
OnRowDeleted="GridView1_RowDeleted" OnRowDeleting="GridView1_RowDeleting"
EmptyDataText="No positions found" OnRowDataBound="GridView1_RowDatabound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="ibEdit" runat="server" AlternateText="Edit"
CommandName="Edit" ImageUrl="~/Images/icon_edit.gif" />
<asp:ImageButton ID="ibDelete" runat="server" AlternateText="Delete"
CommandName="Delete" ImageUrl="~/Images/icon_delete.gif"
OnClientClick='<%# Eval("strPositionName", "return confirm(\"Are you sure you want to delete this entry {0}?\");") %>' />
</ItemTemplate>
<ItemStyle Wrap="False" />
</asp:TemplateField>
//Some controls here
</Columns>
</asp:GridView>
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
//Make delete with the values from the row but event won't fire
}

Gridview outside UpdatePanel not showing

I have an ItemCommand event in a button found in a listview.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:ListView ID="systemsView" runat="server"
onitemcommand="systemsView_ItemCommand">
<ItemTemplate>
<asp:Button ID="btnView" runat="server" Text='<%#Eval("SYSTEM_DESC") %>' CommandArgument='<%# Eval("ROW_ID")%>'
class="systemButtonStyle" />
</ItemTemplate>
</asp:ListView>
</ContentTemplate>
</asp:UpdatePanel>
When the itemCommand is fired I want to bind another gridview which is not inside the update panel. The gridview is not showing when the event is fired. Any ideas how I could solve this problem please?
Since UpdatePanels only perform a PostBack on controls within their ContentTemplate, all controls that are expected to be updated by a Partial PostBack must be housed within the same UpdatePanel's ContentTemplate.
If you need to update something outside of an UpdatePanel with an action that occurs within it's Partial PostBack, you will have to rethink your use of the UpdatePanel.
Two solutions:
Add the other GridView to the UpdatePanel's ContentTemplate.
Remove the UpdatePanel entirely and use the normal PostBack.

ASP.NET LinkButton not invoking 'OnCommand' event

I have a ListView nested inside the column of a GridView, which looks something like this:
<asp:panel id="myPanel" Runat="server" EnableViewState="False">
<asp:GridView id="myDescription" AutoGenerateColumns="False" Width="100%" runat="server"
OnRowCommand="my_RowCommand" OnRowDataBound="GetDataForListView" EnableViewState="False">
<Columns>
<asp:BoundField DataField="id" HeaderText="ID">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="data1" HeaderText="Thing 1">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="data2" HeaderText="Thing2">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="data3" HeaderText="Thing3">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:TemplateField SortExpression="id">
<ItemTemplate>
<asp:HyperLink id="hlView" runat="server" NavigateUrl="...">View</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Column to contain my list of things">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
<ItemTemplate>
<% /* This is my list view: */ %>
<asp:ListView ID="myListView" runat="server" OnItemCommand="DoSomething" EnableViewState="False">
<ItemTemplate>
<asp:LinkButton ID="lbAttachment" Runat="Server" Text='<%# Eval("FILE_NAME") %>'
CommandName='<%# Eval("ROW_NUM") %>' CausesValidation="False" >
</asp:LinkButton><br/>
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:panel>
The data is successfully binding, but the OnCommand event is not being fired on clicking the LinkButton (nor is any other event for the LinkButton, such as an OnClick event).
The rendered HTML for the link button shows that on clicking it, the page is performing a postback: javascript:__doPostBack('...','')
This means it is going back into my 'Page_Load' and refreshing the contents of the page - the grid view is binded here.
I can stop it from performing a postback by adding this attribute to the LinkButton:
OnClientClick="return false;"
But this only stops the postback from occurring, the OnCommand event still doesn't fire.
Any ideas?
The event signature in the code-behind is:
protected void DoSomething(object sender, CommandEventArgs e) { ... }
I have also tried using an OnItemCommand event on the ListView control with this event signature, but similarly the event is not invoked:
protected void DoSomething(object sender, ListViewCommandEventArgs e)
The OnRowdataBound event on the parent GridView is successfully invoked, it's only the nested ListView that fails to invoke its event.
The code I have shown is for the 2nd GridView on the page, there is another one too, and it is this one which gets binded on the Page_Load event. The Page Load event has a sequence of events as follows, where the 1st GridView (which we'll call GridView1) is bound:
Page_Load
Data for GridView is retrieved from database
Data is assigned to a 'DataView' object and assigned to the GridView1 DataSource property.
GridView1.DataBind() is invoked
Miscellaneous conditional logic which removes certain columns from GridView1
An OnClick attribute is added to each row.
So actually, the Page_Load binds the first GridView. The 2nd GridView is the one which contains the ListView which I am having a problem with. This 2nd GridView (the code of which is at the top of the post) is populated on the 'OnRowCommand' event of the 1st GridView, and has a sequence like this:
GetDataForListView
Get data from database
Assign the DataSet containing the data to the DataSource property of the 2nd GridView
Call the DataBind() method
Then, as you can see from the code I posted at the top, I have the OnRowDataBound event which fails to invoke its event in the code-behind.
Ciaran, I replicated the whole scenario and found out the below issue.
Issue: When any event related to either the GridView2 or ListView or the LinkButton is being fired it first hits the Page_load function. In the Page_load function you are not data binding GridView2 and the ListView so apparently they almost vanish and so the Event will not be fired.
Possible Fix:
You need to bind the GridView2 in the Page_load function in order fire those related events and the same goes with the ListView Too.
This fix is a very big one. I am not sure if you could try this.
a. If you are binding the GridView2 depending on the condition generated by the GridView1 click then store those parameters in some hidden field.
b. Have a function named LoadGridView2(parameters) where you bind the GridView2 and the ListView depending on the parameters passed and call this function in the Page_Load function each every time a PostBack is done and pass the stored parameters in the hidden field to the LoadGridView2(parameters)
c. By doing above you can bind the GridView2 according the GirdView1 Click condition and make the GridView2 and ListView available in the PostBack too. So now the event could be fired.
Let me know in case of any queries.
LinkButton has OnCommand, ListVIew has OnItemCommand. So the name isn't correct. OnCommand only fires if the LinkButton has a CommandName set. And also, the repeater may swallow the button's command argument. Certain controls do that because of the way events bubble up to the UI.
<asp:LinkButton ID="linkButton" Runat="Server" OnCommand="DoSomething"
CommandName="DoSomething"
CommandArgument='<%# Eval("ROW_NUM") %>' Text='<%# Eval("FILE_NAME") %>'>
</asp:LinkButton>
Or Try adding:
<asp:ListView .. OnItemCommand=".." />
And then do:
void DoSomething(Object Sender, ListViewCommandEventArgs e) {
// Do something
}
Your button would still need to set a command name like:
<asp:LinkButton .. CommandName="DoSomething" />

Categories

Resources