My recent struggles with adapting to the new WebDataGrid, AJAX, et al., compel me to share something I have learned which I think others will need.
The Scenario:
I have two WebDataGrids contained in an UpdatePanel. Selecting a row in the Parent grid populates the Child grid from a child collection member of the Master grid's datasource (A CSLA object). I am enabling AJAX and using the update panel to improve the user experience.
The Challenge:
The rows in the Child table represent files that have been uploaded to the server. The first column in the grid consists of cells that contain a WebImageButton. Clicking on the button should trigger a browser download of the respective file.
However, certain HttpResponse methods are not supported during asynchronous postbacks, e.g., those coming from controls contained in an UpdatePanel (see http://msdn.microsoft.com/en-us/library/bb386454.aspx?ppud=4).
The Solution:
Through Google, I stumbled upon:
http://justgeeks.blogspot.com/2011/06/how-to-download-file-from-inside.html
In that post, the proposed solution used:
ClientScriptManager.GetPostBackClientHyperlink
which does not seem to work when the calling control is embedded in a WebDataGrid in an UpdatePanel. However, the the author also referenced the following .Net interfaces and methods:
IPostBackEventhandler [See: http://msdn.microsoft.com/en-us/library/system.web.ui.ipostbackeventhandler.aspx]
ClientScriptManager.GetPostBackEventReference(control, string) [See: http://msdn.microsoft.com/en-us/library/system.web.ui.clientscriptmanager.getpostbackeventreference.aspx AND http://msdn.microsoft.com/en-us/library/ms153108.aspx]
Using the above, I created a custom control implementing the IPostBackEventHandler interface, then on the Child grid's InitializeRow event, I found the button, instantiated the custom control and added it to a PlaceHolder, then added a client-side "onClick" attribute to the button that references the custom control's IPostBackEventHandler implementation.
See below:
The Code:
In ASP:
...
<body>
<form id="mainForm" runat="server"">
<asp:PlaceHolder ID="DownloadPlaceHolder" runat="server"> </asp:PlaceHolder>
</form>
</body>
The Custom Control In C#
using System;
using System.IO;using System.Collections.Generic;using System.Linq;using System.Web.UI;
namespace Cww.Web{
public class SynchDownloader : Control, IPostBackEventHandler { private Page thePage;
public SynchDownloader(Page page) { thePage = page; }
public void RaisePostBackEvent(string path) { FileInfo fileInfo = new FileInfo(path); thePage.Response.ClearContent(); thePage.Response.ClearHeaders(); thePage.Response.AddHeader("Content-Disposition", "attachment; filename=" + fileInfo.Name); thePage.Response.AddHeader("Content-Length", fileInfo.Length.ToString()); thePage.Response.TransmitFile(path); thePage.Response.End(); } }}
The CodeBehind in C#:
protected void ChildGrid_InitializeRow(object sender, Infragistics.Web.UI.GridControls.RowEventArgs e)
And Voila!
Hope this is helpful to someone else. I certainly don't know what I'd do without forums like these.
Hi sportfish1850
This is an initial update to let you know that I am looking into your issue. I will have another update for you regarding this matter on or before Friday.
Hello sportfish1850,
Thank you for sharing this information and your experience with getting a full postback to work with a WebDataGrid inside an update panel to download the file you need.
Sincerely,Mike P.Developer Support EngineerInfragistics, Inc.www.infragistics.com