Developing Asp.net pages for the IPAD ~fixing the postback issue
Today I will discuss and solve the challenges that an asp.net developer will face while creating aspx pages with master pages for the IPAD or IPAD 2. The obstacle that asp.net developers have is that when an aspx page is in full screen and the user does nothing for about two minutes all postbacks, but the first, that are not submits will fail to happen. A postback example would be while selecting a new value on a dropdown the selected index changed event is supposed to fire when autopostback="true", assuming that there is a defined method in the code behind, which is wired-up to the event. A person only has search the net for the IPAD cache, viewstate and asp.net issues to find this problem.
With the popularity of the IPAD and the premium for real estate on a mobile device this is an option for .net developers not wanting to learn Objective-C.
JavaScript and Reflection to the rescue!
Add the following code to the masterpage or page with the issue
<input id="MethodX" name="MethodX" type="hidden" runat="server" />
<input id="SenderX" name="SenderX" type="hidden" runat="server" />
<script type="text/javascript">
function Xjump(sender, method) {
document.getElementById('<%=SenderX.ClientID %>').value = sender;
document.getElementById('<%=MethodX.ClientID %>').value = method;
document.forms[0].submit();
}
</script>
Call the following code during the page load, which is in the masterpage or a base page.
public partial class YourAspPage
{
protected void Page_Load(object sender, EventArgs e)
{
Housekeaping();
}
}
This code is assuming that the above code is in the masterpage hence, the Masterpage.findcontrol() .
protected virtual void Housekeaping()
{
var senderX = this.MasterPage.FindControl("SenderX") as HtmlInputHidden;
var method = this.MasterPage.FindControl("MethodX") as HtmlInputHidden;
if (!string.IsNullOrWhiteSpace(senderX.Value))
{
CallBaseMethod(senderX.Value, method.Value);
senderX.Value = string.Empty;
method.Value = string.Empty;
}
}
The following code will execute the desired method
public void CallBaseMethod(string sender, string methodAndArgs)
{
var oPage = this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance |
BindingFlags.FlattenHierarchy);
var obj = oPage.Where(w => w.Name == sender).FirstOrDefault().GetValue(this)
List<object> lstO = new List<object>();
lstO.Add(obj); //sender
var spl = methodAndArgs.Split(',').ToList();
string method;
if (spl.Count() > 1)
{
method = spl[0];
for (int i = 1; i < spl.Count(); i++)
{
lstO.Add(spl[i]);
}
}
else
{
method = methodAndArgs;
lstO.Add(null); //args
}
this.GetType().GetMethod(method, BindingFlags.NonPublic | BindingFlags.Instance |
BindingFlags.FlattenHierarchy).Invoke(this, lstO.ToArray());
}
Asp.net code
<asp:DropDownList ID="ddl" runat="server" CausesValidation="false"
DataTextField="X" DataValueField="X"
onchange="Xjump(ddl','ddl_SelectedIndexChanged')"
OnDataBound="ddlDataBound"/>
Notice the onchange JavaScript function, XJump's Parameter are the ID and the serverside method we want called, which has no parameters.
The following is an example with a server side method that has parameters.
Unfortunately in order to get sorting to work for a grid view, we need to use asp: TemplateFields instead of asp: BoundFields.
<asp:TemplateField SortExpression="ColumnName">
<HeaderTemplate>
<a id="Label1" runat="server" onclick="Xjump('CurrentGridView','Sort,ColumnName')" >
Column Title </a>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lblbla" runat="server" Text='<%#Bind("ColumnName") %>' />
</ItemTemplate>
</asp:TemplateField>
The Code Behind method for the sort
protected virtual void Sort(object sender, string Column)
{
var gv = (GridView)sender;
if (gv.SortDirection == SortDirection.Ascending)
{
gv.Sort(Column, SortDirection.Descending);
}
else
{
gv.Sort(Column, SortDirection.Ascending);
}
}
In conclusion, we end up manually doing some of what asp.net should do for us, but this is far better than having to write the pages in strait html and JavaScript.