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!
Related
I have a button inside a Gridview. What I want to do is when the button is clicked simply change the button color.
However, after publishing the paged and clicking the button nothing happens.
Am I missing a step.
Here is my .aspx code
<asp:GridView id="gvStatus" runat="server" AutoGenerateColumns="false" BorderWidth="1px" BackColor="White" CellPadding="3" CellSpacing="2" BorderStyle="Solid" BorderColor="Black" GridLines="Both" Pager="10" OnRowDataBound="setcolor" OnRowCommand="setsingle" >
<Columns>
<asp:TemplateField HeaderText="1" Visible="true" HeaderStyle-CssClass= "hdrBase" ItemStyle-CssClass="GridBase">
<ItemTemplate>
<asp:Button id="btnDOne" Width="35px" Height ="25px" runat="server" Text='<%#(Eval("dateone", "{0:ddd}"))%>' CommandName="GetData" CommandArgument="<%#((GridViewRow) Container).RowIndex %>" ></asp:Button>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And here is the c#
protected void setsingle(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "GetData")
{
//Get row index
int rowindex = Convert.ToInt32(e.CommandArgument);
////Get Row
GridViewRow gvr = gvStatus.Rows[rowindex];
//Find the button
Button DayButton = gvr.FindControl("btnDOne") as Button;
//Set the color of the button
DayButton.BackColor = Color.Cyan;
}
To test if the code was working added a linkbutton to the Gridview and gave it the same CommandName:
<asp:TemplateField HeaderText="1" Visible="true" HeaderStyle-CssClass= "hdrBase" ItemStyle-CssClass="GridBase">
<ItemTemplate>
<asp:Button id="btnDOne" Width="35px" Height ="25px" runat="server" Text='<%#(Eval("dateone", "{0:ddd}"))%>' CommandName="GetData" CommandArgument='<%# Container.DataItemIndex %>' ></asp:Button>
<asp:LinkButton id="lbd1" runat="server" Text="clickme " CommandName="GetData" CommandArgument='<%# Container.DataItemIndex %>'/>
</ItemTemplate>
</asp:TemplateField>
So, the linkbutton executes the behind code no problem. But the commandbutton does not execute anything. In the last code snippet you will notice I compared the two and basically made the commandbutton match the linkbutton as far as the CommandArgument goes.
I have verified the behind code works, as well as the CommandName assignment is correct.
Is there a different way to do this for a commandbutton?
I ended up abandoning the command buttons and going with the link buttons then setting the back-color of the Grid cell as needed.
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.
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)
{
}
}
An event bound to a DropDownList in a standalone GridView obviously would work in this fashion , but things are bit more complicated in this scenario.
The event does not fire for the DropDownList. What's interesting is the event bound to the Button Does fire. Not sure what the difference would be between the DropDownList and TextBox.
I've tried both OnSelectedIndexChanged and OnTextChanged - neither work.
The nesting is as follows:
GridView A
Ajax Accordion
GridView B (With DropDownList)
<AjaxToolkit:AccordionPane ID="AccordionPane1" runat="server">
<Header>
</Header>
<Content>
<asp:GridView runat="server" ID="gv" AutoGenerateColumns="false"
BorderWidth="0" AlternatingRowStyle-BorderStyle="None" ShowFooter="true">
<Columns>
<asp:TemplateField HeaderText="Id">
<ItemTemplate>
<asp:Label runat="server" ID="lblId" Text='<%# Eval("Id") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Type">
<ItemTemplate>
<asp:Label runat="server" ID="lblType"></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:DropDownList runat="server" ID="ddlType" OnTextChanged="ddlType_SelectedIndexChanged"
AutoPostBack="true">
</asp:DropDownList>
<asp:Button runat="server" ID="btnTest" OnClick="btnTest_Click" Text="TEST" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</Content>
Thank you!
UPDATE
Turns out this had nothing to do with the nested GridViews or Accordion.
After adding the following, the event now successfully fires:
if (!Page.IsPostBack)
Populate(object);
Turns out this had nothing to do with the nested GridViews or Accordion.
After adding the following, the event now successfully fires:
if (!Page.IsPostBack)
Populate(obj);
IGNORE THIS:
I was rebinding the grid in the Onload method.
I have a grid view with some textboxes, which I have to wrap in a UpdatePanel Control. So it looks like this:
<asp:UpdatePanel ID="upDistribution" runat="server" OnLoad="upDistribution_OnLoad">
<ContentTemplate>
<asp:GridView ID="gvDistributions" runat="server" AutoGenerateColumns="false"
OnRowDataBound="gvDistributions_RowDataBound"
CssClass="TallCells ContrastTable MaxWidth LeftHeaders"
GridLines="Both" ShowFooter="True" style="">
<RowStyle HorizontalAlign="Left" />
<EmptyDataTemplate>
No pricing history data found.
</EmptyDataTemplate>
<Columns>
<asp:TemplateField HeaderText="PriceA">
<ItemTemplate>
<asp:TextBox ID="txtPriceA" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="DistPrice">
<ItemTemplate>
<asp:TextBox ID="txtDistPrice" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
There is a button "Save" when I would like to get the value entered for the txtboxes. If there is no UpdatePanel around the GV, i can can easily get the txtbox values like:
((TextBox)gvDistributions.Rows[0].Cells[0].FindControl("txtPriceA")).Text
But when, the GridView is wrapped with UpdatePanel, the above statement returns the value that was set on the page load.
How can I get the value of the text box without getting rid of the updatePanel. I need the update panel, because the number of rows, and dates are dependent on another variable in another user control.
As per my understanding, you should use a trigger for the update panel which is something like below.
<asp:UpdatePanel ...>
<ContentTemplate>
...
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
Hope this helps!!
Use your TextBoxes with their AutoPostBack property set True
<asp:TextBox ID="txtPriceA" runat="server" AutoPostBack="True"/>
I was rebinding gridview in the onLoadMethod