Ok, this may seem a bit silly but I don’t think I’ve gone down this particular path before.
I need to create a custom template column in a DataGrid and add several hyperlinks into the same column. The hyperlinks need to then post back to the page and be handled. Because there are multiple links in the same column I don't think button columns and the grid fired events work in this case.
I haven’t gone done this path because in most applications I simply tend to use classic style postbacks with a query string and be done with it. In this particular app this doesn’t work for a variety of reasons because the page is fairly complex and the query string parameters interfere. The other approach is to use a Button Column and then handle the Command event for the button which is fairly straight forward as well.
But if you end up doing your own postbacks to the same page things get a bit more ugly. I wonder whether there isn’t a better way than what I’m doing, which works just fine but feels a bit like a hack.
So inside of my datagrid I have a template column that does basically this:
<asp:templatecolumn headertext="Comment">
<headerstyle horizontalalign="Center" width="100px"></headerstyle>
<itemtemplate>
<%# wwUtils.TextAbstract( Eval("Comment") ) %>
<br /><i>
<a href="javascript:__doPostBack('btn_DownloadStatus','<%# Eval("Pk")%>')">
<%# Eval("Downloaded") %></a>
| <a href="javascript:if ( confirm('Are you sure you want to delete this invoice?') ) { __doPostBack('btn_Delete','<%# Eval("Pk")%>') }" >Delete</a>
</i>
</itemtemplate>
</asp:templatecolumn>
I’m using hand coded __doPostBack() script calls to force a post back to the form. Inside of the __doPostBack() calls I use a couple of LinkButtons that I stuck on the form to act as the event target for the clicks. They’re in the form and invisible through their style settings:
<!-- Command Handler Buttons. These are invisible and only used to handle delete and downloaded events -->
<asp:LinkButton ID="btnDelete" runat="server" Text="Button" OnClick="btnDelete_Click" Visible="true" style="display:none" />
<asp:LinkButton ID="btnDownloadStatus" runat="server" Text="Button" OnClick="btnDownloadStatus_Click" Visible="false" style="display:none" />
I then have a the Click handlers hooked up to these invisible buttons. Note that I have to use a style to hide the control – visible is required to get the __doPostBack() method rendered into the HTML. Hmmm… isn’t there method on the Page or ClientScript object to force this to render? I sure couldn’t find it short of having a control active that implements IPostBackHandler.
From there I can read the EventArgument to get my context for the record I’m working with which in this case is a Pk for the item:
/// <summary>
/// Handles the grid's Download toggle operation
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnDownloadStatus_Click(object sender, EventArgs e)
{
int Pk = 0;
if (int.TryParse(Request.Form["__eventArgument"], out Pk))
{
if (!Invoice.Load(Pk))
this.lblErrorMessage.Text = Invoice.ErrorMessage + ".";
else
{
Invoice.Entity.Downloaded = !Invoice.Entity.Downloaded;
Invoice.Save();
}
}
}
Now all of this works well actually, but it just doesn’t feel right <g>. I feel like I’m beating ASP.NET into submission with this low level approach and it sure took a bit of trial and error just to arrive here…
So, is there a more official way to accomplish this?
Other Posts you might also like