Thursday, September 30, 2010

How to build an addable DropDownList (can add items using JavaScript )


Demo:

Sometimes asp.net developers find when they change the items collection in a DropDownList in the client side using JavaScripts in the very next postback they run in to Event Validation error. Yes, this is true, because any attacker can inject malicious items to the item list rather than the proper rendered list, they can break down your site. But the problem is there are some legitimate instances where we intentionally add items the DropDownList in the client side using JavaScripts.

This article provides a solution to add items at the client side without Event Validation errors. Idea is the handle item list in hidden field and mark the hidden field as the actual control. So in a postback, actually item list will not get validated but the hidden field get validated.
 No problem so far, but how we can merge newly added items with excising items? For this, by the time I render the control, I add comma separated list of items as the value of hidden field. Then on the event of adding new items to the list in the client side, inside the JavaScript it appends the newly added items to the hidden field value. So job is almost done, then what we all need to do is, get the hidden field value in the LoadPostBackData event and repopulate the item list. Vola job done.

Control itself it renders the item adding JavaScript event (ready made) so all you need to do is call the JavaScript function with three parameters 

Param1 - value of new item
Param2 - text of new item
Param3 - id of the DropDownList - ClientID
AddListItem(value, text, targetListId);

Markup:
<%@ Register Assembly="ActiveTest" Namespace="ActiveTest" TagPrefix="asp" %>
<%@ Page Language="C#" %>
<html>
<head runat="server">
    <script language="javascript" type="text/javascript">
        function AddItem() {
 
            var value = document.getElementById('<%=txtValue.ClientID %>').value;
            var text = document.getElementById('<%=txtText.ClientID %>').value;
            var targetListId = '<%=addlFreeDownDownList.ClientID %>';
 
            AddListItem(value, text, targetListId);
            return false;
        } 
       
    </script>
</head>
<body>
    <form id="form1" runat="server">
        Add Item - 
        Text: <asp:TextBox runat="server" ID="txtText" /> 
        Value: <asp:TextBox runat="server" ID="txtValue" />
        <asp:Button runat="server" ID="btnAdd" Text="Add" OnClientClick="javascript:return AddItem()" />
        <hr />
        <asp:AddableDropDownList runat="server" ID="addlFreeDownDownList">
            <asp:ListItem>Orange</asp:ListItem>
            <asp:ListItem>Blue</asp:ListItem>
            <asp:ListItem>Red</asp:ListItem>
            <asp:ListItem>Yellow</asp:ListItem>
            <asp:ListItem>Black</asp:ListItem>
        </asp:AddableDropDownList>
        <hr />
        <asp:Button runat="server" ID="btnSave" Text="Save" />
    </form>
</body>
</html>

Control:
public class AddableDropDownList : DropDownList
{
    private string script = @"
    function AddListItem(value, text, target) {
        var list = target + ""List"";
        var option = document.createElement(""option"");
        document.getElementById(list).options.add(option);
        option.text = text;
        option.value = value;
        var target = document.getElementById(target);
        if (target.value == """") target.value = value + ""=="" + text;
        else target.value = target.value + "",:,"" + value + ""=="" + text;
        return false;
    } 
";
    public string ListID
    {
        get
        {
            return this.ClientID + "List";
        }
    }
    protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
    {
        string items = postCollection[postDataKey];
        this.Items.Clear();
        if (string.IsNullOrEmpty(items)) return true;
        foreach (string item in Regex.Split(items, ",:,"))
        {
            string[] s = Regex.Split(item, "==");
            if (s.Length != 2)
                throw
                    new Exception("Invalid item the list, list item cannot have == or ,:, combinations");
            this.Items.Add(new ListItem(s[1], s[0]));
        }
        this.SelectedValue = postCollection[postDataKey + "List"];
        return true;
    }
    protected override void Render(HtmlTextWriter writer)
    {
        StringBuilder content = new StringBuilder();
        if (this.AutoPostBack)
        {
            StringBuilder script = new StringBuilder(this.Attributes["onchange"]);
            if (script.Length == 0) script.AppendFormat("javascript:{0}",
                            string.Format("__doPostBack('{0}','');"this.ClientID));
            else
            {
                if (!script.ToString().EndsWith(";")) script.Append(";");
                script.AppendFormat("__doPostBack('{0}','');"this.ClientID);
            }
            this.Attributes.Add("onchange", script.ToString());
        }
        StringBuilder b = new StringBuilder();
        HtmlTextWriter h = new HtmlTextWriter(new StringWriter(b));
        this.Attributes.Render(h);
        content.AppendFormat("<select id=\"{0}List\" name=\"{1}List\"{2}{3}>",
                this.ClientID, this.UniqueID,
                b.Length == 0 ? string.Empty : string.Format(" {0}", b.ToString()),
                !string.IsNullOrEmpty(this.CssClass) ?
                    string.Format(" class=\"{0}\""this.CssClass) : string.Empty);
        foreach (ListItem item in this.Items)
            content.AppendFormat("<option value=\"{0}\"{1}>{2}</option>",
                item.Value, item.Selected ? " selected=\"selected\"" : string.Empty, item.Text);
        content.Append("</select>");
        content.AppendFormat("<input type=\"hidden\" id=\"{0}\" name=\"{1}\"  value=\"{2}\" />",
                this.ClientID, this.UniqueID, this.GetValue());
        writer.Write(content.ToString());
    }
    private string GetValue()
    {
        StringBuilder value = new StringBuilder();
        foreach (ListItem item in this.Items)
        {
            if (value.Length != 0) value.Append(",:,");
            value.AppendFormat("{0}=={1}", item.Value, item.Text);
        }
        return value.ToString();
    }
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), this.GetType().Name, this.script, true);
    }
}

How to redirect users to certain page based or username or user role

Step 1:
You need to setup default as intermidiate page. I have called it as Transfer.aspx
<authentication mode="Forms">
  <forms
    loginUrl="~/Login.aspx"
    defaultUrl="~/Transfer.aspx" />
</authentication>
Step 2:
Then please consider setup role based authenticaiton to relevent folders,
  <location path="Admin">
    <system.web>
      <authorization>
        <allow roles="Admin"/>
        <deny users="?"/>
      </authorization>
    </system.web>
  </location>
  <location path="Members">
    <system.web>
      <authorization>
        <allow roles="Member"/>
        <deny users="?"/>
      </authorization>
    </system.web>
  </location>
In the tranfer aspx page.
Point 1:  If you need a just perticular user, to redirect to a certain page, you can simple use user's name.
Transfer.aspx
<%@ Page Language="C#" %>
<script runat="server">
    protected override void OnLoad(EventArgs e)
    {
        if (this.Page.User != null && this.Page.User.Identity.IsAuthenticated)
        {
            if (this.Page.User.Identity.Name.Equals("Admin"))
                this.Response.Redirect("~/Admin/Default.aspx");
            else
                this.Response.Redirect("~/Member/Default.aspx");
        }
        else this.Response.Redirect("~/Login.aspx");
    }
</script>
Point 2:  If you need grop of users (role based) to redirect to a certain page,
Transfer.aspx
<%@ Page Language="C#" %>
<script runat="server">
    protected override void OnLoad(EventArgs e)
    {
        if (this.Page.User != null && this.Page.User.Identity.IsAuthenticated)
        {
            if (this.Page.User.IsInRole("Admin"))
                this.Response.Redirect("~/Admin/Default.aspx");
            else if (this.Page.User.IsInRole("Member"))
                this.Response.Redirect("~/Member/Default.aspx");
            else
                this.Response.Redirect("~/Default.aspx");
        }
        else this.Response.Redirect("~/Login.aspx");
    }
</script>

How to show the progress of long running operation - Detailed Example

Demo:

Showing progress of a long running operation and keep screen up to date with what is happen in the server side is one common tasks one of a common task in web development. In this scenario, I have used UpdatePanel to wrap the bit I need to update and then a separate thread as the worker. Simply in the button click event of the Do Task button, I start a thread and hand over the long running task to the thread execution
Thread thread = new Thread(new ThreadStart(SomeLongOperation));
thread.Start();
 And also I set the progress bar visible true and set up initial message. As well as I have couple of flags in the Session to tell that the state of the page. They are Processing and Completed. I set Processing  flag to true and Completed flag to false and register start-up script to refresh the page in a while.
this.lblMessage.Text = "<br />Processing... Please wait...";
this.pnlProgress.Width = new Unit(this.Step * this.blockWidth);
this.pnlProgress.Visible = true;
this.Processing = true;
ScriptManager.RegisterStartupScript(thisthis.GetType(),
    this.GetType().Name, string.Format(script, this.UpdatePanel1.UniqueID), true);
Then in the next page load, because Processing flag is true I can keep updating the progress bar and status messages until Completed flag toggle back to true.
if (this.Processing)
{
    if (!string.IsNullOrEmpty(this.LastStatus))
    {
       this.pnlProgress.Width = new Unit(this.Step * this.blockWidth);
       this.lblMessage.Text += string.Format("<br />{0}"this.LastStatus);
       this.LastStatus = string.Empty;
    }                
    ScriptManager.RegisterStartupScript(thisthis.GetType(),
       this.GetType().Name, string.Format(script, this.UpdatePanel1.UniqueID),
       true);
}
else
{
    if (!this.Completed)
    {
       lblMessage.Text += "<br />Processing is complete";
       this.Completed = true;
    }
    else
    {
       this.lblMessage.Text = string.Empty;
       this.Step = 0;
    }
}

Complete Example:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Threading" %>
<html>
<head runat="server">
    <script runat="server">
        private string script = @"setTimeout(""__doPostBack('{0}','')"", 3000);";
        protected int totalSteps = 7;
        private int blockWidth = 50;
        private string styles = @"
            <style type=""text/css"">
                .Hide {{ display:none; }}
                .ProgressWrapper {{ height:22px; width:{0}px; 
                        border:solid 1px #9C9C9C; padding:5px; background-color:#ddd; }}
                .Progress {{ height:20px; background-color:#0059FF; 
                        border:solid 1px #003EB0; float:left; }}
            </style>
        ";
        public bool Processing
        {
            get { return (bool)(Session["Processing"] ?? false); }
            set { Session["Processing"] = value; }
        }
        public int Step
        {
            get { return (int)(Session["Step"] ?? 0); }
            set { Session["Step"] = value; }
        }        
        public string LastStatus
        {
            get { return (string)(Session["LastStatus"] ?? string.Empty); }
            set { Session["LastStatus"] = value; }
        }
        public bool Completed
        {
            get
            {
                return (bool)(Session["Completed"] ??
                    (Session["Completed"] = true));
            }
            set { Session["Completed"] = value; }
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (this.Processing)
            {
                if (!string.IsNullOrEmpty(this.LastStatus))
                {
                    this.pnlProgress.Width = new Unit(this.Step * this.blockWidth);
                    this.lblMessage.Text += string.Format("<br />{0}"this.LastStatus);
                    this.LastStatus = string.Empty;
                }                
                ScriptManager.RegisterStartupScript(thisthis.GetType(),
                    this.GetType().Name, string.Format(script, this.UpdatePanel1.UniqueID),
                    true);
            }
            else
            {
                if (!this.Completed)
                {
                    lblMessage.Text += "<br />Processing is complete";
                    this.Completed = true;
                }
                else
                {
                    this.lblMessage.Text = string.Empty;
                    this.Step = 0;
                }
            }
            if (this.Page.Header != null)
                this.Page.Header.Controls.Add(
                    new Literal() { Text = string.Format(this.styles, 
                        this.totalSteps * this.blockWidth + 2) });
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(SomeLongOperation));
            thread.Start();
            this.lblMessage.Text = "<br />Processing... Please wait...";
            this.pnlProgress.Width = new Unit(this.Step * this.blockWidth);
            this.pnlProgress.Visible = true;
            this.Processing = true;
            ScriptManager.RegisterStartupScript(thisthis.GetType(),
                this.GetType().Name, string.Format(script, this.UpdatePanel1.UniqueID), true);
        }
        void SomeLongOperation()
        {
            this.Completed = false;
            ///
            /// this is just to demonstrate
            /// should you have your own logic there
            /// and change the last status accordingly
            /// 
            for (int i = 0; i < 25; i++)
            {
                if (i % 4 == 0)
                {
                    this.Step = this.Step + 1;
                    string status = string.Format("Step {0} - {1}", i / 4 + 1,
                        DateTime.Now.Ticks % 2 == 0 ? "Success" : "Faild - Due to {exception details}");
                    if (string.IsNullOrEmpty(this.LastStatus))
                        this.LastStatus = status;
                    else this.LastStatus = string.Format("{0}<br />{1}"this.LastStatus, status);
                }
                Thread.Sleep(1000);
            }
            this.Processing = false;
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager runat="server" ID="pageScriptManager" />
    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
        <ContentTemplate>
            <asp:Button runat="server" ID="btnDoTask" Text="Do Task" OnClick="Button1_Click" />
            <hr />
            <asp:Panel runat="server" ID="pnlProgressWrapper" CssClass="ProgressWrapper">
                <asp:Panel runat="server" ID="pnlProgress" CssClass="Progress" Visible="false" />
            </asp:Panel>
            <hr />
            <asp:Label runat="server" ID="lblMessage" />
        </ContentTemplate>
    </asp:UpdatePanel>
    </form>
</body>
</html>

How to access server control values in JavaScripts

  1. In a Page
  2. In a UserControl

How to upload multiple files?

  1. Using FlistList control example
  2. Using third party jQuery + flash plugin example

How to add controls on a button click?

  1. Basic example
  2. Simple example - (Row of controls)
  3. Using DropDownList value example
  4. Using TextBox value example
  5. Full example - (Row of controls)

How to access code behind using JavaScripts?

  1. Using page methods
  2. Using ICallBackEventHandler

How to import data to SQL Server?

  1. How to import a Excel file
  2. How to import a CSV file

How to open a popup?

  1. How to open a popup using asp.net panel
  2. How to open a new window after executing some code
  3. How to create a popup window in code behind

How to print a page?

  1. How to print background colours
  2. How to print fit to page
  3. How to print using JavaScripts
  4. How to hide header and footer while printing
  5. How to save and print

How to copy/delete/rename files and folders?

  1. How to delete files
  2. How to rename files
  3. How to delete folder
  4. How to copy files
  5. How to find folder size?
  6. How to copy file from one server to another

How to bind asp.net menu?

  1. How to bind to a datatable with the relationship with ParentId and Id
  2. How to remove menu item using JavaScripts
  3. How to bind to a XML file
  4. How to bind multiple site map files
  5. How to combine two menus to work together

How to post data to a different page?

  1. Using postback url
  2. Using HttpWebRequest and HttpWebResponse

How to serialize?

  1. XML serialization
  2. Binary serialization
  3. Generic serialization method 
  4. Generic deserialization method

How to work with IFRAMES?

  1. How to pass a value parent to child
  2. How to dynamically load a IFRAME from code behind
  3. How to find which page iframe is embedded in
  4. How to load html page inside aspx page

How to upload a file?

  1. How to upload a file?
  2. How to validate file type in client side?
  3. How to find file size in client side?
  4. How to find file last modified date in client side?
  5. How to find file created date in client side?
  6. How to validate file type in server side?
  7. How to handle files which exceeds the limits?
  8. How to show the selected image without saving the image on the disk?
  9. How to rename the file if the filename exists in the folder while uploading? 

How to build a custom control?

  1. How to build a custom TextBox?
  2. How to build a templated control?
  3. How to implement a collection property?
  4. How to build a custom checkbox control?
  5. How to clone a control?
  6. How to build a resettable panel?
  7. How to build a directory browser? 

How to bubble up events from UserControls to page?

  1. Using delegates
  2. Using bubble event

How to use asp.net caching?

  1. Invalidate response cache based on a condition?
  2. How get/set list item from/to cache

How to work with asp.net calendar?

  1. How to disable weekends
  2. How to disable a day based on criteria
  3. How to disable past days in asp.net calender

How to use asp.net forms authentication?

  1. How to configure simple authentication setup
  2. How to provide a timeout message
  3. How to protect static file types like .xml, .html etc
  4. How to redirect users to certain page based on their username or user role

How to find which control caused a postback

  1. Inside the dedicated event handler
  2. Outside the dedicated event handler

Wednesday, September 29, 2010

How to save details and print a page

Demo:
Useful links:
  1. Opening a window after postback
  2. Java script print function
  3. Apply diffrnet styles whlie printing
  4. Print fit to page and backgrounds
Example:
<%@ Page Language="C#" %>
<html>
<head runat="server">
    <script runat="server">
        private string script = @"
         window.open('{0}','',
                'scrollbars=no,menubar=no, height=600,width=800,resizable=yes,toolbar=no,location=no,status=no');
        ";
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            string m = this.Request.QueryString.Get("mode");
            if (!string.IsNullOrEmpty(m))
            {
                this.ClientScript.RegisterStartupScript(this.GetType(), this.GetType().Name,
                                                                        "window.print();"true);
                this.btnSaveAndPrint.Visible = false;
            }
            else this.btnSaveAndPrint.Visible = true;
        }
        protected void SaveAndPrint(object sender, EventArgs e)
        {
            string page = this.Request.Url.ToString();
            if (page.Contains("?")) page = page + "&mode=print";
            else page = page + "?mode=Print";
            ///
            /// Save your data...
            ///
            Page.ClientScript.RegisterClientScriptBlock(
                this.GetType(),
                this.GetType().Name,
                string.Format(this.script, page),
                true);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <h1>
        Thank you for purchaing our products</h1>
    <hr />
    <asp:TextBox runat="server" ID="txtName" Text="Name" /><br />
    <asp:TextBox runat="server" ID="txtAddress" Text="Address" /><br />
    <asp:TextBox runat="server" ID="txtEmail" Text="mail@email.com" /><br />
    <asp:TextBox runat="server" ID="txtPhone" Text="0123456789" /><br />
    <hr />
    <p>
        I started this site in 2005 to write down simple but important code snippets which
        I may forget easily. Most of the posts/articles published in this site are not rock
        complicated but they are simple answers to questions, which people may find hard
        to remember How To Do them. Today in 2010, almost all posts/articles are common
        answers to the questions raised in Asp.net Forms. All of these posts/articles been
        tested against certain criteria which suits to subject of the post. But it is essential
        you to understand the domain of the post and apply them in appropriate context.
        Most of the posts have being through couple of reviews after feedback from asp.net
        community users. However I DO NOT provide any warranty for these code snippets,
        which may work in your application context. Use these examples at your own risk.
        However if you find obvious syntax error or typo, please feel free to let me know
        by commenting them, so that I can improve the post for other asp.net community users
        of this site. Please remember you are NOT ALLOWED to COPY entire articles/posts
        and publish them your context without my knowledge and permission.
    </p>
    <asp:Button runat="server" ID="btnSaveAndPrint" Text="Save and Print" OnClick="SaveAndPrint" />
    </form>
</body>
</html>

How to show the progress of long running operation

  1. Simple example - only strat message and end message
  2. Detailed example - including progress bar and step processing results
  3. How to show the progress of a request - using JavaScripts and CSS

How to get around EventValidation error

  1. How to input HTML text with out EventValidation error
  2. How to add/change items to DropDownList in the client side without EventValidation error

Tuesday, September 28, 2010

How to search a GridView on a key press event

Demo:

I am using asp.net UpdatePanel control to partial page update. As there is no keyup event for the asp.net TextBox control, I add an attribute to the control in the page load, which postbacks the update panel on the keyup event of the TextBox.
this.txtDepartment.Attributes.Add("onkeyup", 
    string.Format("javascript:__doPostBack('{0}','')"this.upnlGridView.ClientID));
 For selecting, I have used DataTable’s Select(...) method.
DataRow[] rows = this.DataTable.Select(string.Format("Department LIKE '%{0}%'"this.txtDepartment.Text));
Then to identify the update panel postback event I have used __EVENTTARGET parameter of the Request’s Form[...] collection. If the __EVENTTARGET is equal to update panel’s ClientID then perform search based on TextBox value.
string target = this.Request.Form["__EVENTTARGET"];
if (!string.IsNullOrEmpty(target) && target.Equals(this.upnlGridView.ClientID))
{
    if (!string.IsNullOrEmpty(this.txtDepartment.Text))
    {
        DataRow[] rows = this.DataTable.Select(
            string.Format("Department LIKE '%{0}%'"this.txtDepartment.Text));
        this.grvItems.DataSource = this.LoadData(rows);
        this.grvItems.DataBind();
    }
    else
    {
        this.grvItems.DataSource = this.DataTable;
        this.grvItems.DataBind();
    }
}
For the demonstration purposes I have constructed a DataTable, but certainly you may get data from the database. To keep the example simple I have not implemented the search and paging. I leave it up to you to add suitable code. And also if it take a while to update you can improve the user experience by adding UpdateProgress where you can place little spinning image.

Example:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<html>
<head id="Head1" runat="server">
 <script runat="server">
        string[] departments = { "Development""Accounting", 
                                   "Sales""Marketting""Management""Human Resouces" };
        private DataTable DataTable
        {
            get { return (DataTable)Session["DataTable"]; }
            set { Session["DataTable"] = value; }
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (!this.IsPostBack)
            {
                DataTable dt;
                if (this.DataTable == null)
                    dt = this.DataTable = this.LoadData();
                else dt = this.DataTable;
                this.grvItems.DataSource = dt;
                this.grvItems.DataBind();
                this.txtDepartment.Attributes.Add("onkeyup",
                    string.Format("javascript:__doPostBack('{0}','')"this.upnlGridView.ClientID));
            }
            else
            {
                string target = this.Request.Form["__EVENTTARGET"];
                if (!string.IsNullOrEmpty(target) && target.Equals(this.upnlGridView.ClientID))
                {
                    if (!string.IsNullOrEmpty(this.txtDepartment.Text))
                    {
                        DataRow[] rows = this.DataTable.Select(
                            string.Format("Department LIKE '%{0}%'"this.txtDepartment.Text));
                        this.grvItems.DataSource = this.LoadData(rows);
                        this.grvItems.DataBind();
                    }
                    else
                    {
                        this.grvItems.DataSource = this.DataTable;
                        this.grvItems.DataBind();
                    }
                }
            }
        }
        protected void PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
        }
        protected void Sorting(object sender, GridViewSortEventArgs e)
        {
        }
        private DataTable LoadData()
        {
            return this.LoadData(null);
        }
        private DataTable LoadData(DataRow[] rows)
        {
            DataTable dt = this.GetTable();
            if (rows == null)
            {
                ///
                /// To demonstrate I have loaded data table in the code
                /// You may load this data from database.
                ///
                Random r = new Random();
                for (int i = 0; i < 300; i++)
                    dt.Rows.Add(
                        string.Format("E{0:000}", i),
                        departments[r.Next(0, 5)],
                        "Employee" + i,
                        string.Format("07967781{0:000}", i),
                        string.Format("employee{0:000}@company.com", i));
            }
            else
                foreach (DataRow r in rows) dt.Rows.Add(r[0], r[1], r[2], r[3], r[4]);
            return dt;
        }
        private DataTable GetTable()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("EmpID"String.Empty.GetType());
            dt.Columns.Add("Department"String.Empty.GetType());
            dt.Columns.Add("Name"String.Empty.GetType());
            dt.Columns.Add("Phone"String.Empty.GetType());
            dt.Columns.Add("Email"String.Empty.GetType());
            return dt;
        }         
 </script>
</head>
<body>    
 <form id="form1" runat="server">
        <asp:ScriptManager runat="server" ID="PageScriptManager" />
        Search Department: 
        <asp:TextBox 
            runat="server" 
            ID="txtDepartment"                    
            AutoPostBack="true" />
        <asp:UpdatePanel runat="server" ID="upnlGridView">
            <ContentTemplate>
                <hr />
                <asp:GridView 
                    runat="server" 
                    ID="grvItems" 
                    AllowPaging="true" 
                    AllowSorting="true" 
                    OnSorting="Sorting" 
                    OnPageIndexChanging="PageIndexChanging" 
                    CellPadding="5">                
                </asp:GridView>
            </ContentTemplate>
        </asp:UpdatePanel>
 </form>
</body>
</html>

iPhone Launch Screen Sizes

iPhone Portrait iOS 8 Retina HT 5.5 = 1242 X 2208 Retna HD 4.7 = 750 X 1134 iPhone Landscape iOS 8 Retina HD 5.5  2208 X 1242 iPho...