Click here to Skip to main content
15,886,199 members
Articles / Web Development / ASP.NET

Pagination Class for ASP.NET MVC

Rate me:
Please Sign up or sign in to vote.
4.38/5 (17 votes)
15 Aug 2008CPOL3 min read 104.7K   6.4K   37  
A class for creating different types of pagination link in ASP.NET MVC.
// ********************************************************************
// Document     : Pagination.cs
// Version      : 1.0
// Category     : Libraries
// Description  : This is a pagination class for creating different types 
//                of page links.
// Author       : Mohammad Jahedur Rahman
// Date         : 08/03/2008
// Copyright    : Copyright (c) Valentica. All rights reserved.
// ********************************************************************

using System;
using System.IO;
using System.Text;
using System.Xml.Linq;

namespace Valentica.Libraries
{
    /// <summary>
    /// Pagination type enumeration
    /// </summary>
    public enum PaginationType
    {
        /// <summary>
        /// Default page link
        /// </summary>
        Default,

        /// <summary>
        /// Default page link with item on the right 
        /// </summary>
        DefaultWithItemRight,

        /// <summary>
        /// Default page link with item on the left
        /// </summary>
        DefaultWithItemLeft,

        /// <summary>
        /// Previous, next page link
        /// </summary>
        PreviousNext,

        /// <summary>
        /// Previous, next page link with item on the right
        /// </summary>
        PreviousNextItemRight,

        /// <summary>
        /// Previous, next page link with item on the left
        /// </summary>
        PreviousNextItemLeft,

        /// <summary>
        /// Previous, next page link with item on the center
        /// </summary>
        PreviousNextItemCenter,

        /// <summary>
        /// First, previous, next, last page link
        /// </summary>
        FirstPreviousNextLast,

        /// <summary>
        /// First, previous, next, last page link with item on the right
        /// </summary>
        FirstPreviousNextLastItemRight,

        /// <summary>
        /// First, previous, next, last page link with item on the left
        /// </summary>
        FirstPreviousNextLastItemLeft,

        /// <summary>
        /// First, previous, next, last page link with item on the center
        /// </summary>
        FirstPreviousNextLastItemCenter,

        /// <summary>
        /// Number page link
        /// </summary>
        Number,

        /// <summary>
        /// Number page link with item on the right
        /// </summary>
        NumberWithItemRight,

        /// <summary>
        /// Number page link with item on the left
        /// </summary>
        NumberWithItemLeft
    }

    /// <summary>
    /// Item type enumeration
    /// </summary>
    public enum ItemTypes
    {
        /// <summary>
        /// Displaying (n) to (n) of (n) Items
        /// </summary>
        Item,

        /// <summary>
        /// Page (n) of (n)
        /// </summary>
        Page,

        /// <summary>
        /// (n)/(n)
        /// </summary>
        Digit
    }

    /// <summary>
    /// Pagination class
    /// </summary>
    public class Pagination
    {
        #region Private Properties

        #region General Properties

        private int     _perPage         = 10;   // Max number of items you want shown per page
        private int     _numLinks        = 2;    // Number of "digit" links to show before/after the currently viewed page

        #endregion

        #region Link Properties

        private string  _firstLink       = "&lsaquo; First";
        private string  _nextLink        = "&gt;";
        private string  _prevLink        = "&lt;";
        private string  _lastLink        = "Last &rsaquo;";

        #endregion

        #region Tag Properties

        private string  _fullTagOpen     = "";
        private string  _fullTagClose    = "";
        private string  _firstTagOpen    = "";
        private string  _firstTagClose   = "&nbsp;";
        private string  _lastTagOpen     = "&nbsp;";
        private string  _lastTagClose    = "";
        private string  _curTagOpen      = "&nbsp;<b>";
        private string  _curTagClose     = "</b>";
        private string  _nextTagOpen     = "&nbsp;";
        private string  _nextTagClose    = "&nbsp;";
        private string  _prevTagOpen     = "&nbsp;";
        private string  _prevTagClose    = "";
        private string  _numTagOpen      = "&nbsp;";
        private string  _numTagClose     = "";
        private string  _itemTagOpen     = "<strong>&nbsp;&nbsp;";
        private string  _itemTagClose    = "</strong>&nbsp;&nbsp;";

        #endregion

        private ItemTypes _itemType = ItemTypes.Item;

        #endregion

        #region Public Property Accessors

        #region General Property Accessors
    
        /// <summary>
        /// Gets or sets url to controller/action.
        /// </summary>
        public string BaseUrl { get; set; }

        /// <summary>
        /// Gets or sets the total rows in the result set.
        /// </summary>
        public int TotalRows { get; set; }

        /// <summary>
        /// Gets or sets the number item per page.
        /// </summary>
        public int PerPage
        {
            get { return _perPage; }
            set { _perPage = value; }
        }

        /// <summary>
        /// Gets or sets the number of "digit" links before and after the selected page number.
        /// </summary>
        public int NumLinks
        {
            get { return _numLinks; }
            set { _numLinks = value; }
        }

        /// <summary>
        /// Gets or sets the current selected page.
        /// </summary>
        public int CurPage { get; set; }

        #endregion

        #region Link Property Accessors

        /// <summary>
        /// Gets or sets the text to be shown in the "first" link on the left.
        /// </summary>
        public string FirstLink
        {
            get { return _firstLink; }
            set { _firstLink = value; }
        }

        /// <summary>
        /// Gets or sets the text to be shown in the "next" page link.
        /// </summary>
        public string NextLink
        {
            get { return _nextLink; }
            set { _nextLink = value; }
        }

        /// <summary>
        /// Gets or sets the text to be shown in the "previous" page link.
        /// </summary>
        public string PrevLink
        {
            get { return _prevLink; }
            set { _prevLink = value; }
        }

        /// <summary>
        /// Gets or sets the text to be shown in the "last" link on the right.
        /// </summary>
        public string LastLink
        {
            get { return _lastLink; }
            set { _lastLink = value; }
        }

        #endregion

        #region Tag Property Accessors

        /// <summary>
        /// Gets or sets the opening tag placed on the left side of the entire result.
        /// </summary>
        public string FullTagOpen
        {
            get { return _fullTagOpen; }
            set { _fullTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag placed on the right side of the entire result.
        /// </summary>
        public string FullTagClose
        {
            get { return _fullTagClose; }
            set { _fullTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "first" link.
        /// </summary>
        public string FirstTagOpen
        {
            get { return _firstTagOpen; }
            set { _firstTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "first" link.
        /// </summary>
        public string FirstTagClose
        {
            get { return _firstTagClose; }
            set { _firstTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "last" link.
        /// </summary>
        public string LastTagOpen
        {
            get { return _lastTagOpen; }
            set { _lastTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "last" link.
        /// </summary>
        public string LastTagClose
        {
            get { return _lastTagClose; }
            set { _lastTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "current" link.
        /// </summary>
        public string CurTagOpen
        {
            get { return _curTagOpen; }
            set { _curTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "current" link.
        /// </summary>
        public string CurTagClose
        {
            get { return _curTagClose; }
            set { _curTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "next" link.
        /// </summary>
        public string NextTagOpen
        {
            get { return _nextTagOpen; }
            set { _nextTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "next" link.
        /// </summary>
        public string NextTagClose
        {
            get { return _nextTagClose; }
            set { _nextTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "previous" link.
        /// </summary>
        public string PrevTagOpen
        {
            get { return _prevTagOpen; }
            set { _prevTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "previous" link.
        /// </summary>
        public string PrevTagClose
        {
            get { return _prevTagClose; }
            set { _prevTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "digit" link.
        /// </summary>
        public string NumTagOpen
        {
            get { return _numTagOpen; }
            set { _numTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "digit" link.
        /// </summary>
        public string NumTagClose
        {
            get { return _numTagClose; }
            set { _numTagClose = value; }
        }

        /// <summary>
        /// Gets or sets the opening tag for the "Item".
        /// </summary>
        public string ItemTagOpen
        {
            get { return _itemTagOpen; }
            set { _itemTagOpen = value; }
        }

        /// <summary>
        /// Gets or sets the closing tag for the "Item".
        /// </summary>
        public string ItemTagClose
        {
            get { return _itemTagClose; }
            set { _itemTagClose = value; }
        }

        #endregion

        /// <summary>
        /// Gets or sets the item type.
        /// </summary>
        public ItemTypes ItemType
        {
            get { return _itemType; }
            set { _itemType = value; }
        }

        #endregion

        /// <summary>
        /// Gets or sets the total number of pages
        /// </summary>
        private int NumPages { get; set; }

        #region Public Constructors

        public Pagination()
        {
        }

        public Pagination(bool loadFromXml)
        {
            if (!loadFromXml)
            {
                return;
            }
  
            string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Content\Pagination.xml");

            this.LoadPaginationXml(file);                
        }

        /// <summary>
        /// Load the Pagination Configuration from Xml
        /// </summary>
        /// <param name="xmlFile">string, Pagination.xml File Path</param>
        public void LoadPaginationXml(string xmlFile)
        {
            XElement element;

            try
            {
                element = XElement.Load(xmlFile);

                var properties = element.Elements();

                foreach (var property in properties)
                {
                    SetPaginationSettings(property.Name.ToString(), property.Value);
                }
            }
            catch (FileNotFoundException)
            {

            }
            catch (Exception)
            {

            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Get the page links
        /// </summary>
        /// <returns>Page link string</returns>
        public string GetPageLinks()
        {
            return this.GetPageLinks(PaginationType.Default);
        }

        /// <summary>
        /// Get the page links
        /// </summary>
        /// <param name="pageType">Pagination type</param>
        /// <returns>Page link string</returns>
        public string GetPageLinks(PaginationType pageType)
        {
            // If anything invalid
            if (!this.IsValidSettings())
                return "";

            // Add a trailing slash to the base URL if needed
            if (!this.BaseUrl.Trim().EndsWith("/"))
                this.BaseUrl = this.BaseUrl + "/";

            // And here we go...
            StringBuilder pageLink = new StringBuilder();

            switch (pageType)
            {
                case PaginationType.Default:
                    this.BuildDefaultLink(pageLink);
                    break;

                case PaginationType.DefaultWithItemRight:
                    this.BuildDefaultLink(pageLink);
                    this.BuildItemLink(pageLink);
                    break;

                case PaginationType.DefaultWithItemLeft:
                    this.BuildItemLink(pageLink);
                    this.BuildDefaultLink(pageLink);
                    break;

                case PaginationType.PreviousNext:
                    this.BuildPreviousNextLink(pageLink);
                    break;

                case PaginationType.PreviousNextItemRight:
                    this.BuildPreviousNextLink(pageLink);
                    this.BuildItemLink(pageLink);
                    break;

                case PaginationType.PreviousNextItemLeft:
                    this.BuildItemLink(pageLink);
                    this.BuildPreviousNextLink(pageLink);
                    break;

                case PaginationType.PreviousNextItemCenter:
                    this.BuildPreviousLink(pageLink, false);
                    this.BuildItemLink(pageLink);
                    this.BuildNextLink(pageLink, false);
                    break;

                case PaginationType.FirstPreviousNextLast:
                    this.BuildFirstPreviousNextLastLink(pageLink);
                    break;

                case PaginationType.FirstPreviousNextLastItemRight:
                    this.BuildFirstPreviousNextLastLink(pageLink);
                    this.BuildItemLink(pageLink);
                    break;

                case PaginationType.FirstPreviousNextLastItemLeft:
                    this.BuildItemLink(pageLink);
                    this.BuildFirstPreviousNextLastLink(pageLink);
                    break;

                case PaginationType.FirstPreviousNextLastItemCenter:
                    this.BuildFirstLink(pageLink, false);
                    this.BuildPreviousLink(pageLink, false);
                    this.BuildItemLink(pageLink);
                    this.BuildNextLink(pageLink, false);
                    this.BuildLastLink(pageLink, false);
                    break;

                case PaginationType.Number:
                    this.BuildDigitLink(pageLink);
                    break;

                case PaginationType.NumberWithItemRight:
                    this.BuildDigitLink(pageLink);
                    this.BuildItemLink(pageLink);
                    break;

                case PaginationType.NumberWithItemLeft:
                    this.BuildItemLink(pageLink);
                    this.BuildDigitLink(pageLink);
                    break;

                default:
                    this.GetPageLinks(PaginationType.Default);
                    break;
            }

            pageLink.Insert(0, this.FullTagOpen);
            pageLink.Append(this.FullTagClose);

            return pageLink.ToString();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Set the Pagination Configuration Settings
        /// </summary>
        /// <param name="propertyName">Configuration Property Name</param>
        /// <param name="propertyValue">Configuration Property Value</param>
        private void SetPaginationSettings(string propertyName, string propertyValue)
        {
            switch (propertyName)
            {
                #region Set General Properties

                case "BaseUrl":
                    this.BaseUrl = propertyValue;
                    break;

                case "TotalRows":
                    this.TotalRows = Convert.ToInt32(propertyValue);
                    break;

                case "PerPage":
                    this.PerPage = Convert.ToInt32(propertyValue);
                    break;

                case "NumLinks":
                    this.NumLinks = Convert.ToInt32(propertyValue);
                    break;

                case "CurPage":
                    this.CurPage = Convert.ToInt32(propertyValue);
                    break;

                #endregion

                #region Set Link Properties

                case "FirstLink":
                    this.FirstLink = propertyValue;
                    break;

                case "NextLink":
                    this.NextLink = propertyValue;
                    break;

                case "PrevLink":
                    this.PrevLink = propertyValue;
                    break;

                case "LastLink":
                    this.LastLink = propertyValue;
                    break;

                #endregion

                #region Set Tag Properties

                case "FullTagOpen":
                    this.FullTagOpen = propertyValue;
                    break;

                case "FullTagClose":
                    this.FullTagClose = propertyValue;
                    break;

                case "FirstTagOpen":
                    this.FirstTagOpen = propertyValue;
                    break;

                case "FirstTagClose":
                    this.FirstTagClose = propertyValue;
                    break;

                case "LastTagOpen":
                    this.LastTagOpen = propertyValue;
                    break;

                case "LastTagClose":
                    this.LastTagClose = propertyValue;
                    break;

                case "CurTagOpen":
                    this.CurTagOpen = propertyValue;
                    break;

                case "CurTagClose":
                    this.CurTagClose = propertyValue;
                    break;

                case "NextTagOpen":
                    this.NextTagOpen = propertyValue;
                    break;

                case "NextTagClose":
                    this.NextTagClose = propertyValue;
                    break;

                case "PrevTagOpen":
                    this.PrevTagOpen = propertyValue;
                    break;

                case "PrevTagClose":
                    this.PrevTagClose = propertyValue;
                    break;

                case "NumTagOpen":
                    this.NumTagOpen = propertyValue;
                    break;

                case "NumTagClose":
                    this.NumTagClose = propertyValue;
                    break;

                #endregion

                default:
                    break;
            }
        }

        /// <summary>
        /// Check if everythings are ok
        /// </summary>
        /// <returns>Boolean</returns>
        private bool IsValidSettings()
        {
            // If our item count or per page total is zero there is no need to continue.
            if (this.TotalRows == 0 && this.PerPage == 0)
                return false;

            // Calculate the total number of pages
            this.NumPages = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(this.TotalRows) / Convert.ToDouble(this.PerPage)));

            // Is there only one page? Hm... nothing more to do here then.
            if (NumPages == 1)
                return false;

            // Is the current page equals to 0 then return
            if (this.CurPage == 0)
                return false;

            // Is the current page beyond the result range then return
            if (((this.CurPage - 1) * this.PerPage) > this.TotalRows)
                return false;

            return true;
        }

        /// <summary>
        /// Build the "First" link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        /// <param name="isDefault">bool, isDefault</param>
        private void BuildFirstLink(StringBuilder pageLink, bool isDefault)
        {
            if (isDefault)
            {
                if (this.CurPage > this.NumLinks)
                {
                    pageLink.Append(this.FirstTagOpen);
                    pageLink.Append("<a href='" + this.BaseUrl + "1" + "'>");
                    pageLink.Append(this.FirstLink);
                    pageLink.Append("</a>");
                    pageLink.Append(this.FirstTagClose);
                }
            }
            else
            {
                pageLink.Append(this.FirstTagOpen);

                if (this.CurPage != 1)
                {
                    pageLink.Append("<a href='" + this.BaseUrl + "1" + "'>");
                    pageLink.Append(this.FirstLink);
                    pageLink.Append("</a>");
                }
                else
                {
                    pageLink.Append(this.FirstLink);
                }

                pageLink.Append(this.FirstTagClose);
            }
        }

        /// <summary>
        /// Build the "Previous" link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        /// <param name="isDefault">bool, isDefault</param>
        private void BuildPreviousLink(StringBuilder pageLink, bool isDefault)
        {
            if (isDefault)
            {
                if ((this.CurPage - this.NumLinks) >= 0)
                {
                    int i = this.CurPage - 1;

                    if (i == 0) i = 1;

                    pageLink.Append(this.PrevTagOpen);
                    pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(i) + "'>");
                    pageLink.Append(this.PrevLink);
                    pageLink.Append("</a>");
                    pageLink.Append(this.PrevTagClose);
                }
            }
            else
            {
                int i = this.CurPage - 1;

                pageLink.Append(this.PrevTagOpen);

                if (i > 0)
                {
                    pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(i) + "'>");
                    pageLink.Append(this.PrevLink);
                    pageLink.Append("</a>");
                }
                else
                {
                    pageLink.Append(this.PrevLink);
                }

                pageLink.Append(this.PrevTagClose);
            }
        }

        /// <summary>
        /// Build the "Digits" link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        private void BuildDigitLink(StringBuilder pageLink)
        {
            // Calculate the start and end numbers. These determine
            // which number to start and end the digit links with
            int start = ((this.CurPage - this.NumLinks) > 0) ? this.CurPage - (this.NumLinks - 1) : 1;
            int end = ((this.CurPage + this.NumLinks) < NumPages) ? this.CurPage + this.NumLinks : NumPages;

            for (int loop = start - 1; loop <= end; loop++)
            {
                int i = (loop * this.PerPage) - this.PerPage;

                if (i >= 0)
                {
                    // Current page
                    if (this.CurPage == loop)
                    {
                        pageLink.Append(this.CurTagOpen);
                        pageLink.Append(loop);
                        pageLink.Append(this.CurTagClose);
                    }
                    else
                    {
                        pageLink.Append(this.NumTagOpen);
                        pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(loop) + "'>");
                        pageLink.Append(loop);
                        pageLink.Append("</a>");
                        pageLink.Append(this.NumTagClose);
                    }
                }
            }
        }

        /// <summary>
        /// Build the "Next" Link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        /// <param name="isDefault">bool, isDefault</param>
        private void BuildNextLink(StringBuilder pageLink, bool isDefault)
        {
            if (isDefault)
            {
                if (this.CurPage < NumPages)
                {
                    pageLink.Append(this.NextTagOpen);
                    pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(this.CurPage + 1) + "'>");
                    pageLink.Append(this.NextLink);
                    pageLink.Append("</a>");
                    pageLink.Append(this.NextTagClose);
                }
            }
            else
            {
                int i = this.CurPage + 1;

                pageLink.Append(this.NextTagOpen);

                if (i <= NumPages)
                {
                    pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(i) + "'>");
                    pageLink.Append(this.NextLink);
                    pageLink.Append("</a>");
                }
                else
                {
                    pageLink.Append(this.NextLink);
                }

                pageLink.Append(this.NextTagClose);
            }
        }

        /// <summary>
        /// Build the "Last" link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        /// <param name="isDefault">bool, isDefault</param>
        private void BuildLastLink(StringBuilder pageLink, bool isDefault)
        {
            if (isDefault)
            {
                if ((this.CurPage + this.NumLinks) < NumPages)
                {
                    pageLink.Append(this.LastTagOpen);
                    pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(NumPages) + "'>");
                    pageLink.Append(this.LastLink);
                    pageLink.Append("</a>");
                    pageLink.Append(this.LastTagClose);
                }
            }
            else
            {
                pageLink.Append(this.LastTagOpen);

                if (this.CurPage != NumPages)
                {
                    pageLink.Append("<a href='" + this.BaseUrl + Convert.ToString(NumPages) + "'>");
                    pageLink.Append(this.LastLink);
                    pageLink.Append("</a>");
                }
                else
                {
                    pageLink.Append(this.LastLink);
                }

                pageLink.Append(this.LastTagClose);
            }
        }

        /// <summary>
        /// Build the "Item" link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        private void BuildItemLink(StringBuilder pageLink)
        {
            pageLink.Append(this.ItemTagOpen);

            if (this.ItemType == ItemTypes.Item)
            {
                int start   = (this.CurPage - 1) * this.PerPage + 1;
                int end     = this.CurPage * this.PerPage;
                
                end     = (end > this.TotalRows)? this.TotalRows : end; 

                pageLink.Append("Displaying " + start.ToString() + 
                                " to " + end.ToString() +
                                " of " + this.TotalRows.ToString() + " Items");
            }
            else if (this.ItemType == ItemTypes.Page)
                pageLink.Append("Page " + this.CurPage.ToString() + " of " + this.NumPages.ToString());
            else if (this.ItemType == ItemTypes.Digit)
                pageLink.Append(this.CurPage.ToString() + "/" + this.NumPages.ToString());

            pageLink.Append(this.ItemTagClose);
        }

        /// <summary>
        /// Build the Default link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        private void BuildDefaultLink(StringBuilder pageLink)
        {
            this.BuildFirstLink(pageLink, true);
            this.BuildPreviousLink(pageLink, true);
            this.BuildDigitLink(pageLink);
            this.BuildNextLink(pageLink, true);
            this.BuildLastLink(pageLink, true);
        }

        /// <summary>
        /// Build the PreviousNext link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        private void BuildPreviousNextLink(StringBuilder pageLink)
        {
            this.BuildPreviousLink(pageLink, false);
            this.BuildNextLink(pageLink, false);
        }

        /// <summary>
        /// Build the FirstPreviousNextLast link
        /// </summary>
        /// <param name="pageLink">StringBuilder, pageLink</param>
        private void BuildFirstPreviousNextLastLink(StringBuilder pageLink)
        {
            this.BuildFirstLink(pageLink, false);
            this.BuildPreviousLink(pageLink, false);
            this.BuildNextLink(pageLink, false);
            this.BuildLastLink(pageLink, false);
        }
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Bangladesh Bangladesh
Software Engineer, Bangladesh.

Comments and Discussions