Postback a linkbutton in a grid that's under an UpdatePanel - asp.net

as my title says...
How do you make a LinkButton fire a POSTBACK (not ASYNCPOSTBACK) which is inside a GridView and is under an UpdatePanel?
My Scenario is this,
I have a grid. say table A, which populates a Linkbuttons with link to do Server.Transfer calls from Page1 to Page2.
I have a good reason why i am using a Server.Transfer because of previous page referencing methods and Response.Redirect doesnt fit at all.
normally it would work if i add the grid as a Postback trigger in the UpdatePanel like so
<Triggers><asp:PostBackTrigger ControlID="gvitem" /></Triggers>
but since I have another control inside the grid that needs to be do an AsyncPostback, that would not work also,
all that's lacking is have this line of code, do postback.
<asp:TemplateField HeaderText="Description" SortExpression="ShortDesc">
<ItemTemplate>
<asp:LinkButton ID="btndesc" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "ShortDesc")%>' CommandName="Edit" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "Key") %>' />
</ItemTemplate>
</asp:TemplateField>
anyone have an idea?

Find btndesc on grid.ItemDataBound and register it as a PostBackTrigger.

Related

Cannot remove viewstate hidden field

I have a massive viewstate hidden field that is causing my application to be unworkable. I have tried:
EnableViewState="false" on every control
EnableViewState="false" in page directive
Page.EnableViewState = false in Page_Init
<pages enableViewState="false" /> in web.config
The page causing the issue has a single GridView which I want to render once only, so I don't ever need the viewstate.
I examined the hidden field using this tool, and there is apparently hardly any info in it (since I disabled the property in every control probably). For some reason though, the page insists on including a hidden field that is thousands and thousands of lines long.
How can I get rid of this field (or reduce it to a usable size) for good?
Here is an exert from the offending GridView:
<asp:GridView ID="MyGrid" runat="server" AutoGenerateColumns="False"
EnableModelValidation="True" EnableViewState="False"
CssClass="my-report">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<span title='title' class="abbr">My ID</span>
</HeaderTemplate>
<ItemTemplate>
<%# Eval("my_id") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<span title='title2' class="abbr">Second col heading</span>
</HeaderTemplate>
<ItemTemplate>
<asp:ListView ID="MyListView" runat="server" EnableViewState="False">
<LayoutTemplate>
<ul>
<asp:PlaceHolder runat="server" ID="itemPlaceHolder" EnableViewState="False" />
</ul>
</LayoutTemplate>
<ItemTemplate>
<li><%# Eval("field_2")%></li>
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The hidden field you see on the page is not only for ViewState, it also contains the ControlState. There is no way to disable the control state so you'll need to find a way to live with it. How many items the grid is displaying?
As a last option you may consider compressing generated viewstate field.
Here you have an MSDN article explaining how ControlState works
If your GridView is non-interactive (that is, it doesn't contain any child controls that post back), then you can reduce the size of view state by waiting until the page's Render method is called to bind the grid:
Protected Overrides Sub Render(writer As HtmlTextWriter)
MyGrid.DataSource = ...
MyGrid.DataBind()
MyBase.Render(writer)
End Sub
In case anyone has a similar problem, it was occuring because I had a ListView inside each row of the grid. I replaced the ListView with a Repeater and the viewstate is no longer a problem.
Another option is to use Flesk.ViewState something.
It can put the viewstate on files, compress it, session, etc.
Like the others say, sometimes is inevitable in ASPNET to live with ViewState.
Thats why your best option is to move to MVC :)

UpdatePanel quits responding after Response.TransmitFile

I have a GridView in an UpdatePanel that shows a list of files. One of the columns in the GridView is a button that opens the listed PDF file.
<asp:UpdatePanel runat="server" ID="upPurchaseOrder">
<ContentTemplate>
<asp:GridView ID="gvPurachaseOrder" runat="server" AutoGenerateColumns="False" DataSourceID="odsPurchaseOrders"
EnableModelValidation="True" DataKeyNames="PurchaseOrderID,PromotionID" onrowcreated="gvPurachaseOrder_RowCreated">
<Columns>
<%--BoundFields omitted--%>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Button ID="btnPurchaseOrderOpen" runat="server" Text="Open" CommandName="Open"
CommandArgument='<%# Eval("FilePath") %>' oncommand="btnPurchaseOrderOpen_Command" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
In the RowCreated event I register btnPurchaseOrderOpen as a PostBack control, so it causes a full postback.
In the button event handler, I open the file with the Response.TransmitFile method.
Response.Clear();
Response.ContentType = GetConentTypeForFile(fi.Extension);
Response.AddHeader("content-disposition", String.Format("attachment;filename={0}", fi.Name));
Response.TransmitFile(fi.FullName);
Response.End();
My problem is that after the file is opened (it opens correctly) the UpdatePanel stops updating. I can click the other buttons and they never post back synchronously or asynchronously. I have a feeling the problem is related to the response, but I don't know how to fix it.
You are doing a full post back but you are not returning any new page to the server since you are only doing transmitfile and then response.end. It's basically a dead end for your page. The way you may want to get around this is to do the full post back in an iframe or simply create a direct link to the download file, even if that might be a ashx handler where you can continue to have similar logic to what you are already using.

Paging for Listview inside a Gridview not working

I have a listview nested inside a gridview.
I'm trying to get paging working on the listview. I thought that it would display the paging controls, and just page through them normally.
It does display the controls, and limits the result set shown to the appropriate number of records (pageSize) but when I click on the paging controls the grid refreshes and nothing changes with the nested listview (it's still on the first page).
I've tried nesting the listview inside an updatepanel, but the behavior remains. The gridview itself is already in an updatepanel.
So this is the layout I've got:
<Gridview ID="gvApplications" DataSourceID="odsApplications" DataKeyNames="ID" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="Functions">
<ItemTemplate>
<asp:ListView ID="lvFunctions" runat="server" DataSource='<%#Eval("ApplicationFunctions") %>'
DataKeyNames="ID">
<LayoutTemplate>
<asp:DataPager ID="dpFunctions" runat="server" PageSize="1" PagedControlID="lvFunctions">
<Fields>
<asp:NextPreviousPagerField />
</Fields>
</asp:DataPager>
<ul>
<li>
<span ID="itemPlaceholder" runat="server" />
</li>
</ul>
</LayoutTemplate>
<ItemTemplate>
<asp:Label ID="lblFunction" runat="server" Text='<%# Eval("ApplicationFunction.Name") %>' />
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</Gridview>
Ideas?
Honestly, I would consider using a master-details pattern here. There are a lot of code examples on this. For example:
Google: Master Details Examples with Child Objects
There are also scenarios where the details view (child objects in your case) would display on a separate page. Either way, by displaying the child objects in a separate details view, you avoid the coding and display issues that come with nesting.
Matt Berseth has some of the best code examples out there on this topic:
http://mattberseth.com/blog/gridview/
Listview / datapager combination do not work properly if the listview does not use a datasource control.
Try including a datasource control (objectdatasource could be applicable) in the template field.

Multiple databound controls in a single GridView column

I have a grid view that is data bound to a dataset. In a grid I have a column DefaultValue, which has three controls in it - a dropdownlist, a checkbox and a textbox. Depending on the data that is coming in it can switch to any of these controls. Everything is simple enough when we need just to display data - in gridview_prerender event I simply make one of the controls visible. The control is setup like following:
<asp:TemplateField HeaderText="Default Value" SortExpression="DefaultValue">
<ItemTemplate>
<asp:TextBox ID="txt_defaultValue_view" runat="server" Text='<%# Bind("DefaultValue") %>' Enabled ="false" />
<asp:DropDownList ID="ddl_defaultValue_view" runat="server" Enabled ="false" />
<asp:CheckBox ID="chk_defaultValue_view" runat="server" Enabled ="false" />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txt_defaultValue_edit" runat="server" Text='<%# Bind("DefaultValue") %>'/>
<asp:DropDownList ID="ddl_defaultValue_edit" runat="server" />
<asp:CheckBox ID="chk_defaultValue_edit" runat="server" />
</EditItemTemplate>
</asp:TemplateField>
My problem starts when I am in edit mode and I need to update the grid with new data. Since only the textbox control is databound, the RowUpdating event can only access data from the textbox column and all of my other data simply gets discarded. I also can't databind with checkbox and dropdownlist control, since they can get an invalid data type exception. So, does anyone know how can I update a column that has three different controls, where each of these three controls might have a valid data?
Thanks
First, i would switch visibility of the controls in RowDataBound of the Grid and not on PreRender, because it can only change on DataBinding and not on every postback.
You can there also bind the Dropdown to its datasource, change the checked-state of the Checkbox and set the Text-property of the Textbox according to the the Dataitem of the Row.
When you update you can find your controls with FindControl in RowUpdating and get their values(f.e. Dropdownlist.SelectedValue).
GridView has pair of events:
RowUpdating/RowUpdated
RowDeleting/RowDeleted
....
In your case your need RowUpdating - is called right before update is performed, So find in row expected control (saying checkbox) and make preparation before pass to database
As another way review possibility to use ObjectDataSource event Updating - it is usual way to specify parameters for query execution.

ASP.NET Setting a DetailsView BoundField value from javascript

I'd like to know if it is possible to set a field of a DetailsView BoundField (in edit mode) from javascript? I can't set an id for the boundfield, so obviously can't use document.getElementById() to get to it, but I was wondering if there's another way to do it?
You could try to create an EditItemTemplate, place a TextBox inside and give it an ID of your choice.
Like this:
<Fields>
<asp:TemplateField HeaderText="Column1">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Fields>
If there is stuff to be bound on the TextBox's Text property you could use Bind() method.
Good Luck.

Resources