Using iTextSharp to generate pdf file in asp.net

One of the common requirement of web applications is to provide users a way to download some contents. In case of a report, almost all of the reporting tools have the export to pdf kind of function available.

But sometime, it is not a report that needs to be generated in pdf. But it could be simple web page or content of a page or sometimes a plain text needs to be generated in pdf format.

There are many third party tools are available for this task. We can import their API's in Asp.net application and it takes care of all core function of creating pdf files. iTexSharp being one of the widely used and Open source (FREE) component, we are going to see how easily it can be used and range of features it provides

Code starting

I intend to cover other features of iTextSharp component. Focus of this article would be on simply creating a pdf file with different sources of text.

To start with, download iTextSharp dll from official page here iTexSharp is a c# version of original Java library iText. To demonstrate the use, i have created a sample web application in c# and added reference to iTextSharp.dll. I wanted to test using some other site's html page as a source to convert into pdf also, i would user entered string to convert into pdf. After creating couple of textboxes for input, I want to write code on button click event.

Before that, lets add few references in our code.

using System.IO;
using iTextSharp;
using iTextSharp.text.api;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html.simpleparser;

In button click event, create object of Document and PDFWriter

Document itextDoc = new Document();
PdfWriter pdfDoc = PdfWriter.GetInstance(itextDoc,Response.OutputStream);

At the end generated PDF file is going to be outputted to outputstream. The following code is just for reading other web page using WebClient and converting response into string reader (or reading text file into stringreader). You may want ignore this code if you are aware about how to do it.

 System.Net.WebClient webClient=new System.Net.WebClient(); 
 //passing url of local web page to read its html content
 Stream responseData = webClient.OpenRead("http://localhost:51951/Test/Default4.aspx");
 //converting stream into stream reader object
 StreamReader inputstream = new StreamReader(responseData);
 //If you want to read text from other source like plain text file or user input, ignore all above lines
 StringWriter sw = new StringWriter();
 HtmlTextWriter writer = new HtmlTextWriter(sw);
 writer.Write(inputstream.ReadToEnd());
 //comment above line and uncomment below line if you wish to convert text file to pdf
 //writer.Write(File.ReadAllText(@"E:\MyFolder\filename.txt"));
 StringReader sr = new StringReader(sw.ToString());

Now that e have the source content, we need to parse the source content for valid HTML format and extract iTextSharp elements. The parsed elements will be returned into List of IElement. We will then need to loop through all elements and add them individually using Document object we just created. Below lines of code will do just that

List<IElement> elements =HTMLWorker.ParseToList(sr,null);  

  itextDoc.Open();
  //htmlwrite.Parse(sr);
  foreach (IElement el in elements)
  {
      itextDoc.Add(el);
  }                  
  itextDoc.Close();

Before adding elements using Document object, Open method is called on Document object and Close afterwards

Lets run the test. I already have another simple asp.net page running in another Visual studio instance. When viewed in browser, the page looks like this

pdf1

From my sample application when I call this page using WebClient and generate the PDF file, it opens up as

pdf2

Our basic task is completed. You might want to add little more stuff to generated PDF. Like adding header/footer, images, watermark etc. Most of these functionality available in ITextSharp. We will look at them in following articles. Please find complete code for this test below.

System.Net.WebClient webClient=new System.Net.WebClient(); 
 //passing url of local web page to read its html content
 Stream responseData = webClient.OpenRead("http://localhost:51951/Test/Default4.aspx");
 //converting stream into stream reader object
 StreamReader inputstream = new StreamReader(responseData);
 //If you want to read text from other source like plain text file or user input, ignore all above lines
 StringWriter sw = new StringWriter();
 HtmlTextWriter writer = new HtmlTextWriter(sw);
 writer.Write(inputstream.ReadToEnd());
 //comment above line and uncomment below line if you wish to convert text file to pdf
 //writer.Write(File.ReadAllText(@"E:\MyFolder\filename.txt"));
 StringReader sr = new StringReader(sw.ToString());

 //Parse into IElement
 List<IElement> elements =HTMLWorker.ParseToList(sr,null);        
 //Open the Document
 itextDoc.Open();
 //loop through all elements
 foreach (IElement el in elements)
 {
     //add individual element to Document
     itextDoc.Add(el);
 }                  
 //Close the document
 itextDoc.Close();
 //set the Response object
 Response.ContentType = "application/pdf";
 Response.AddHeader("content-disposition", "attachment;filename=TestPage.pdf");
 Response.End();

 

Happy coding!

Write C#. Run JavaScript.

BridgeNet

Open Source C# to JavaScript Compiler and Frameworks. Run Your App On Any Device Using JavaScript.

Use Bridge.NET to build platform independent applications for mobile, web and desktop. Run on iOS, Windows, Mac, Linux and billions of other devices with JavaScript support. Compile your C# code into native JavaScript and deploy on Billions of devices.

Try it on bridge.net or fork it on GitHub

UDID

In my previsious post (How do I get a Unique Identifier for a Device within Windows 10 Universal?) I talked about how getting a unique Id for a device. I’ve found another way.

In the registry there is an unique ID generated during Windows installation and it won't change until you reinstall Windows. You can find such ID in HKLM/Software/Microsoft/Cryptography, it's a string named MachineGuid.

If you can identify a component you're pretty sure that won't change (motherboard for example) you may use a simple WMI query to get its serial number but you should always provide a fallback because many many MBs returns a fake S/N (and virtual machines may returns always the same one). What's the proper solution...well it depends on what you have to do with that ID. Identify the user? Check for license? Encrypt data? Each of these has a different "best practice" for ID.

Get an unique ID for the device
If you have to identify a particular device (regardless to the user) you have many options, what I'd prefer to do is to generate an ID using only stable data (S/N from motherboard and BIOS, for example). This won't help you if he/she completely renew its hardware but it should be stable enough (but you have to define what is enough in your case). You may even use the S/N of the primary disk (with portable devices it's pretty stable and you may even use it in combination with other serial numbers to build your own ID). You can get this informations through WMI or (if you're targeting WinRT) through specific bytes of the ASHWID structure.

Encrypt data
In this case you have to think when data may be unrecoverable. If with a small hardware change your users won't be able to read their previous files well, they'll be unhappy. In this case I would suggest to use the MachineGuid, unless they reinstall the OS they wouldn't have to worry (but do them a favor and provide a way to read back that GUID somewhere). If you're sure you're targeting a portable device like a phone or a tablet then disk serial number (or CPU ID, if available, or MB or BIOS) may be appropriate too (because it's pretty uncommon they'll change).

Licensing
I would use a combination of many (stable) IDs. As for an unique identifier for the device you can't be sure nothing will change. In the past MAC address was vastly used for this but mobile devices changed these rules (because it's easy to turn off a NIC). You can still use them but you have to put extra care (and code) to manage that situation. Again a combination of multiple IDs (chosen carefully) can help you to minimize customers effort when they change their hw/sw setup. In this case a good compromise could be the OS serial number (not the MachineGuid). If they install a new OS then they have to update your license too (but I would use it combined with something else to be sure they won't use the same OS copy on multiple computers or virtual machines).

Note about virtual machines
If you have to target VMs too then things become more complicated. In theory an user can create multiple copies of the same VM with exactly the same hardare and software configuration. If this is an issue and if you can't address this properly (for example using a network check) I would suggest you don't support them at all (just quit if you detect a VM).

/// 
/// Here is a code example that filters form ASHWID the hardware modules
/// that are unlikely to be changed (CPU id, size of memory, serial number of the disk device and bios)
/// 
/// 
public string GetDeviceID()
{
    // get the hardware Profile id and convert it to byte Array
    var hardwareToken = Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null);

    byte[] byteArray = null;
    Windows.Security.Cryptography.CryptographicBuffer.CopyToByteArray(hardwareToken.Id, out byteArray);

    var deviceSerial = "";
    var offset = 0;

    // we filter the hardware modules that are unlikely to be changed, and aggregate them to a string.
    while (offset < hardwareToken.Id.Length)
    {
        // CPU ID of the processor || Size of the memory || Serial number of the disk device || BIOS
        if ((byteArray[offset] == 1 || byteArray[offset] == 2 || byteArray[offset] == 3 || byteArray[offset] == 9) && byteArray[offset + 1] == 0)
        {
            for (var i = 0; i < 4; i++)
            {
                deviceSerial += byteArray[offset + i].ToString();
            }
        }
        offset += 4;
    }

    return deviceSerial;
}

 

Happy coding!

How do I get a Unique Identifier for a Device within Windows 10 Universal?

If you google a bit about this problem, you can’t find a right solution because all people are speaking about Hardware Token. Unfortunately this functionality doesn’t exists for Universal Windows Application.

There are at the moment only a way. You have to add the Extension reference "Windows Desktop Extensions for the UWP" or "Windows Mobile Extensions for the UWP", then you can use the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Security.ExchangeActiveSyncProvisioning;
using Windows.System.Profile;

namespace PSC.Code
{
    public sealed class DeviceInfo
    {
        private static DeviceInfo _Instance;
        public static DeviceInfo Instance
        {
            get
            {
                if (_Instance == null)
                    _Instance = new DeviceInfo();
                return _Instance;
            }

        }

        public string Id { get; private set; }
        public string Model { get; private set; }
        public string Manufracturer { get; private set; }
        public string Name { get; private set; }
        public static string OSName { get; set; }

        private DeviceInfo()
        {
            Id = GetId();
            var deviceInformation = new EasClientDeviceInformation();
            Model = deviceInformation.SystemProductName;
            Manufracturer = deviceInformation.SystemManufacturer;
            Name = deviceInformation.FriendlyName;
            OSName = deviceInformation.OperatingSystem;
        }

        private static string GetId()
        {
            if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.System.Profile.HardwareIdentification"))
            {
                var token = HardwareIdentification.GetPackageSpecificToken(null);
                var hardwareId = token.Id;
                var dataReader = Windows.Storage.Streams.DataReader.FromBuffer(hardwareId);

                byte[] bytes = new byte[hardwareId.Length];
                dataReader.ReadBytes(bytes);

                return BitConverter.ToString(bytes).Replace("-", "");
            }

            throw new Exception("NO API FOR DEVICE ID PRESENT!");
        }
    }
}

 

Someone speaks about to use EasClientDeviceInformation provides a unique Id but this is working only for Windows Store Apps.

var deviceInformation = new EasClientDeviceInformation();
string Id = deviceInformation.Id.ToString();

 

Happy coding!

How can I know when SQL Full Text Index Population is finished?

image

When you execute some queries on your SQL Server, are you sure the catalog is being imported?

With this simple script you can know which is the Index status.

DECLARE @CatalogName VARCHAR(MAX)
SET     @CatalogName = 'TEST_FullIndex'

SELECT FULLTEXTCATALOGPROPERTY(@CatalogName,'ItemCount') as NumberOfItems, 
	   FULLTEXTCATALOGPROPERTY(@CatalogName,'ImportStatus') as ImportStatus,
	   DATEADD(ss, FULLTEXTCATALOGPROPERTY(@CatalogName,
                     'PopulateCompletionAge'), '1/1/1990') AS LastPopulated,
    (SELECT CASE FULLTEXTCATALOGPROPERTY(@CatalogName,'PopulateStatus')
        WHEN 0 THEN 'Idle'
        WHEN 1 THEN 'Full Population In Progress'
        WHEN 2 THEN 'Paused'
        WHEN 3 THEN 'Throttled'
        WHEN 4 THEN 'Recovering'
        WHEN 5 THEN 'Shutdown'
        WHEN 6 THEN 'Incremental Population In Progress'
        WHEN 7 THEN 'Building Index'
        WHEN 8 THEN 'Disk Full.  Paused'
        WHEN 9 THEN 'Change Tracking' END) AS Status
FROM sys.fulltext_catalogs AS cat

 

More information about the status or other property on Microsoft https://technet.microsoft.com/en-us/library/ms190370.aspx

ASP.NET Pager Control

This control provides a simple method for adding paging functionality to your ASP.NET site. The control itself is not "attached" to any data source; instead, that is left up to you, the developer, to take care of.

When you have a repeater or other similar controls, you don’t have a paging control. For this reason I’ve created one simple but useful. This is a control and you can customize it how you want.

The control has the following properties:

  • CssClass: for each number
  • CurrentPageCssClass for the current page number
  • Separator: Specify the string that is to appear between the number links
  • FirstText: String to be used for the "first button". Default is "|<"
  • PreviousText: String to be used for the "previous button". Default is "<"
  • NextText: String to be used for the "next button". Default is ">"
  • LastText: String to be used for the "last button". Default is ">|"
  • PageSize: A handy place to store your page sizes, not used in the code
  • NumberOfPages: The number of page links to display in between the previous/next links.
  • ShowGoTo: Displays the GoTo functionality.
  • TotalPages: Required to correctly display the number links

The is one event:

  • OnChange when a user click on a number to change page

There is a method to invoke:

  • GenerateLinks(): use this to generate the links if changes are made, such as the currentPageNumber is changed (either by you, or when the OnChange event is fired)

The event arguments provided are:

  • First: A boolean indicating whether the "first link" has been clicked
  • Previous: A boolean indicating whether the "previous link" has been clicked
  • Next: A boolean indicating whether the "next link" has been clicked
  • Last: A boolean indicating whether the "last link" has been clicked
  • PageSize: The page size you set previously
  • CurrentPageNumber: The number of the current page; this auto increments/decrements when the first/last/previous/next link is clicked

Pager.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Pager.ascx.cs" Inherits="usercontrols_Pager" %>
<asp:LinkButton ID="LinkButtonFirst" runat="server" Text="|<" OnClick="LinkButtonFirst_Click" />
<asp:LinkButton ID="LinkButtonPrevious" runat="server" Text="<" OnClick="LinkButtonPrevious_Click" />
<asp:Repeater ID="RepeaterNumbers" runat="server">
    <ItemTemplate>
        <asp:LinkButton ID="LinkButtonNumber" runat="server" Enabled="<%#!IsCurrentPage((int)Container.DataItem) %>" CssClass="<%#!IsCurrentPage((int)Container.DataItem) ? CssClass : CurrentPageCssClass %>" Text="<%#(int)Container.DataItem%>" OnClick="LinkButtonNumber_Click" />
    </ItemTemplate>
    <SeparatorTemplate>
        <%#Separator%>
    </SeparatorTemplate>
</asp:Repeater>
<asp:LinkButton ID="LinkButtonNext" runat="server" Text=">" OnClick="LinkButtonNext_Click" />
<asp:LinkButton ID="LinkButtonLast" runat="server" Text=">|" OnClick="LinkButtonLast_Click" />
<asp:TextBox ID="TextBoxGoTo" runat="server" Width="30px" /></asp:Label>
<asp:Button ID="ButtonGoTo" runat="server" Text="Go To" OnClick="ButtonGoTo_Click" />

 

Pager.ascx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class usercontrols_Pager : System.Web.UI.UserControl
{
    #region Events
    /// Fires when a  link is clicked, the text with in the object (link button) is the number
    public event EventHandler Change;
    #endregion

    #region Properties
    /// 
    /// Gets or sets total number of pages the datasource is capable of.
    /// 
    public int TotalPages
    {
        get
        {
            if (ViewState["TotalPages"] == null)
            {
                ViewState["TotalPages"] = 0;
            }

            return Convert.ToInt32(ViewState["TotalPages"]);
        }

        set
        {
            ViewState["TotalPages"] = value;
        }
    }

    /// 
    /// Gets or sets the "First" record display text
    /// 
    public string FirstText
    {
        get; set;
    }

    /// 
    /// Gets or sets the "Previous" record display text
    /// 
    public string PreviousText
    {
        get; set;
    }

    /// 
    /// Gets or sets the "Next" record display text
    /// 
    public string NextText
    {
        get; set;
    }

    /// 
    /// Gets or sets the "Last" record display text
    /// 
    public string LastText
    {
        get; set;
    }

    /// 
    /// Gets or sets the seperator display text
    /// 
    public string Separator
    {
        get;
        set;
    }

    /// 
    /// Enables/disables the "GoTo" functionality
    /// 
    public bool ShowGoTo
    {
        get;
        set;
    }

    /// 
    /// Gets or sets the number of pages to display at
    /// 
    public int NumberOfPages
    {
        get
        {
            if (ViewState["NumberOfPages"] == null)
            {
                ViewState["NumberOfPages"] = 10;
            }

            return Convert.ToInt32(ViewState["NumberOfPages"]);
        }

        set
        {
            ViewState["NumberOfPages"] = value;
        }
    }

    /// 
    /// Gets or sets the current page number
    /// 
    public int CurrentPageNumber
    {
        get
        {
            if (ViewState["CurrentPageNumber"] == null)
            {
                ViewState["CurrentPageNumber"] = 1;
            }

            return Convert.ToInt32(ViewState["CurrentPageNumber"]);
        }

        set
        {
            ViewState["CurrentPageNumber"] = value;
        }
    }

    /// 
    /// Gets or sets the page size, mainley used as a helpful reminder
    /// 
    public int PageSize
    {
        get
        {
            if (ViewState["PageSize"] == null)
            {
                ViewState["PageSize"] = 10;
            }

            return Convert.ToInt32(ViewState["PageSize"]);
        }

        set
        {
            ViewState["PageSize"] = value;
        }
    }

    /// 
    /// Gets or sets the css class for the currently selected tab
    /// 
    public string CssClass
    {
        get; set;
    }

    public string CurrentPageCssClass
    {
        get; set;
    }

    #endregion

    #region Public Methods
    ///  Generates the pagers links based upon the controls properties 
    public void GenerateLinks()
    {
        var display = new List();
        int minimum;
        int maximum;
        CalculateBoundry(this.NumberOfPages, this.TotalPages, this.CurrentPageNumber, out minimum, out maximum);
        for (int i = minimum; i <= maximum; i++)
        {
            display.Add(i);
        }

        RepeaterNumbers.DataSource = display;
        RepeaterNumbers.DataBind();

        bool dataToDisplay = this.TotalPages > 0;

        LinkButtonFirst.Visible = dataToDisplay;
        LinkButtonPrevious.Visible = dataToDisplay;
        LinkButtonNext.Visible = dataToDisplay;
        LinkButtonLast.Visible = dataToDisplay;

        if (this.TotalPages < 1 || !this.ShowGoTo)
        {
            this.ButtonGoTo.Visible = false;
            this.TextBoxGoTo.Visible = false;
        }
        else
        {
            this.ButtonGoTo.Visible = true;
            this.TextBoxGoTo.Visible = true;
        }

        this.LinkButtonFirst.Enabled = !(this.CurrentPageNumber <= 1);
        this.LinkButtonPrevious.Enabled = !(this.CurrentPageNumber <= 1);
        this.LinkButtonNext.Enabled = !(this.CurrentPageNumber >= this.TotalPages);
        this.LinkButtonLast.Enabled = !(this.CurrentPageNumber >= this.TotalPages);
        this.LabelTotPages.Text = "/" + TotalPages;
    }
    #endregion

    #region Protected Methods
    /// 
    /// Runs the initlaisation code
    /// 
    /// The object that fired this event
    /// Additional arguments passes
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            this.LinkButtonFirst.Text = this.FirstText ?? "|<";
            this.LinkButtonPrevious.Text = this.PreviousText ?? "<";
            this.LinkButtonNext.Text = this.NextText ?? ">";
            this.LinkButtonLast.Text = this.LastText ?? ">|";
        }
    }

    /// 
    /// Determins if the current page number is the same as the page number passed through
    /// 
    /// Page number to check against
    /// True if they match
    protected bool IsCurrentPage(int pageNumber)
    {
        return pageNumber == this.CurrentPageNumber;
    }

    #region buttons clicked
    /// Fires the FirstClicked event
    /// Object that fires this event
    /// Additional arguments passed
    protected void LinkButtonFirst_Click(object sender, EventArgs e)
    {
        if (this.Change != null)
        {
            this.CurrentPageNumber = 1;
            var args = new PagerEventArgs
            {
                First = true,
                Previous = false,
                Next = false,
                Last = false,
                Number = this.CurrentPageNumber,
                PageSize = this.PageSize
            };
            this.Change(this, args);
        }
    }

    /// Fires the PreviousClicked event
    /// Object that fires this event
    /// Additional arguments passed
    protected void LinkButtonPrevious_Click(object sender, EventArgs e)
    {
        if (this.Change != null)
        {
            this.CurrentPageNumber--;
            var args = new PagerEventArgs
            {
                First = false,
                Previous = true,
                Next = false,
                Last = false,
                Number = this.CurrentPageNumber,
                PageSize = this.PageSize
            };
            this.Change(this, args);
        }
    }

    /// Fires the NumbereClicked event
    /// Object that fires this event
    /// Additional arguments passed
    protected void LinkButtonNumber_Click(object sender, EventArgs e)
    {
        if (this.Change != null)
        {
            var number = Convert.ToInt32(((LinkButton)sender).Text);
            this.CurrentPageNumber = number;
            var args = new PagerEventArgs
            {
                First = false,
                Previous = false,
                Next = false,
                Last = false,
                Number = number,
                PageSize = this.PageSize
            };
            this.Change(this, args);
        }
    }

    /// Fires the NextClicked event
    /// Object that fires this event
    /// Additional arguments passed
    protected void LinkButtonNext_Click(object sender, EventArgs e)
    {
        if (this.Change != null)
        {
            this.CurrentPageNumber++;
            var args = new PagerEventArgs
            {
                First = false,
                Previous = false,
                Next = true,
                Last = false,
                Number = this.CurrentPageNumber,
                PageSize = this.PageSize
            };
            this.Change(this, args);
        }
    }

    /// Fires the LastClicked event
    /// Object that fires this event
    /// Additional arguments passed
    protected void LinkButtonLast_Click(object sender, EventArgs e)
    {
        if (this.Change != null)
        {
            this.CurrentPageNumber = this.TotalPages;
            var args = new PagerEventArgs
            {
                First = false,
                Previous = false,
                Next = false,
                Last = true,
                Number = this.CurrentPageNumber,
                PageSize = this.PageSize
            };
            this.Change(this, args);
        }
    }

    /// Fires the NumbereClicked event
    /// Object that fires this event
    /// Additional arguments passed
    protected void ButtonGoTo_Click(object sender, EventArgs e)
    {
        if (this.Change != null)
        {
            int number;
            if (int.TryParse(this.TextBoxGoTo.Text, out number))
            {
                if (number <= this.TotalPages)
                {
                    this.CurrentPageNumber = number;
                    var args = new PagerEventArgs
                    {
                        First = false,
                        Previous = false,
                        Next = false,
                        Last = false,
                        Number = number,
                        PageSize = this.PageSize
                    };
                    this.Change(this, args);
                }
            }
        }
    }
    #endregion

    #endregion

    #region Private Methods
    /// 
    /// Calculates the upper/lower boundries for the pager to use when generating the page tabs
    /// 
    /// Maximum nuber of pages along the bottom of the pager
    /// Total number of pages in the datasource
    /// Current page number
    /// Returns the lowest boundry
    /// Returns the upper boundry
    private static void CalculateBoundry(int maximumPages, int totalPages, int currentPage, out int lowerBound, out int upperBound)
    {
        if (totalPages < maximumPages)
        {
            lowerBound = 1;
            upperBound = totalPages;
        }
        else
        {
            // NOTE: Look in to saturated arithmetic
            var rightDisplay = maximumPages / 2;
            var leftDisplay = maximumPages - rightDisplay;

            lowerBound = currentPage - leftDisplay;
            var lowerOffset = 0 - lowerBound;

            upperBound = currentPage + rightDisplay + (lowerOffset > 0 ? lowerOffset : 0);
            var upperOffset = upperBound > totalPages ? upperBound - totalPages : 0;
            upperBound = (totalPages - upperBound) > 0 ? upperBound : totalPages;

            lowerBound = lowerBound > 0 ? (lowerBound + lowerBound > upperOffset ? lowerBound - upperOffset + 1 : 1) : 1;
        }
    }

    #endregion
}

/// Event agruments for pager control
public class PagerEventArgs : EventArgs
{
    /// Gets or sets the page number that is fired
    public int Number
    {
        get; set;
    }

    /// Gets or sets a value indicating whether the first button has been click
    public bool First
    {
        get; set;
    }

    /// Gets or sets a value indicating whether the previous button has been click
    public bool Previous
    {
        get; set;
    }

    /// Gets or sets a value indicating whether the next button has been click
    public bool Next
    {
        get; set;
    }

    /// Gets or sets a value indicating whether the last button has been click
    public bool Last
    {
        get; set;
    }

    /// Gets or sets the number of rows each page contains
    public int PageSize
    {
        get;
        set;
    }
}

 

CSS

/* Search page Paging */
.paging a {
    background-color: #dcdcdc;
    padding: 5px 7px;
    text-decoration: none;
    border: 1px solid #dcdcdc;
    margin-left: 3px;
}

    .paging a:hover {
        background-color: #e5e5e5;
        color: #9ea0a3;
        border: 1px solid #9ea0a3;
    }

.paging span {
    padding: 3px 5px;
    color: #000000;
    font-size: 12px;
}

.paging .next {
    margin-left: 3px;
}

.paging a.currentpage {
    background-color: #00AFBD;
    color: #ffffff;
    font-weight: bold;
}

.paging input[type=text] {
    font-size: 12px;
    padding: 3px;
    margin-left: 15px;
    margin-right: 3px;
}

.paging input[type=submit] {
    font-size: 12px;
    padding: 3px;
    margin-right: 3px;
}
Download Pager.zip (2.9KB) usercontrol

Advertsing

125X125_06

TagCloud

MonthList

CommentList