Click here to Skip to main content
15,881,173 members
Articles / Web Development / HTML

Fast GridView

Rate me:
Please Sign up or sign in to vote.
4.27/5 (5 votes)
4 Nov 2008CPOL1 min read 48.2K   603   48  
A fast and optimized GridView.
/*
 * Copyright � 2006, Ashley van Gerven - ashley._v_g_@gmail.com (NB: remove '_' chars)
 * All rights reserved.
 *
 * Use of this script, with or without modification, is permitted
 * provided that the above copyright notice and disclaimer below is not removed.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 */


#define CLR_v1  // << N.B. Comment this line if compiling with .NET 2.0 or later


using System;
using System.ComponentModel;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
using System.Drawing;


#if !CLR_v1
[assembly: WebResource("Avg.Controls.SmartPager.js", "text/javascript")]
#endif


namespace Avg.Controls
{

    public delegate void  OnClickPagerNumberEventHandler(object sender , string pPageNum);
 


	/// <summary>
	/// Flickr-style pager control with a go-to-page feature
	/// </summary>
	[ToolboxData("<{0}:SmartPager runat=\"server\" />")]
	[ToolboxBitmap(typeof(SmartPager), "SmartPagerIcon.bmp")]
	public class SmartPager : Table , ICloneable, IPostBackDataHandler, ICallbackEventHandler,IStateManager
	{
		#region Public Properties


        public event OnClickPagerNumberEventHandler OnClickEvent;

		/// <summary>
		/// Gets or sets the number of page numbers to display in the list
		/// </summary>
		[Category("Appearance"), DefaultValue(9), Description("Number of page numbers to display in the list")]
		public int Display
		{
			get { return display; }
			set { display = value; }
		}

		/// <summary>
		/// Gets or sets the number of pages available in the data source
		/// </summary>
		[Category("Misc"), Description("Number of pages available in the data source")]
		public int PageCount
		{
			get { return pageCount; }
			set { pageCount = value; }
		}

		/// <summary>
		/// Gets or sets the current page number
		/// </summary>
		[Browsable(false)]
		public int CurrentPage
		{
			get { return currentPage; }
			set
			{
				currentPage = value;
				ViewState[ClientID + "_CurrentPage"] = currentPage;
			}
		}

		/// <summary>
		/// Gets or sets a value indicating whether to output the Next & Previous links
		/// </summary>
		[Category("Appearance"), Description("Number of pages available in the data source")]
		public bool OutputNextPrevLinks
		{
			get { return outputNextPrevLinks; }
			set { outputNextPrevLinks = value; }
		}

		/// <summary>
		/// Gets or sets the style for non-clickable Next & Previous links
		/// </summary>
		[Category("Appearance"), Description("Number of pages available in the data source")]
		public string DisabledNextPrevStyle
		{
			get { return disabledNextPrevStyle; }
			set { disabledNextPrevStyle = value; }
		}

		/// <summary>
		/// Gets or sets the text for the 'Previous' link
		/// </summary>
		[Category("Appearance"), Description("Number of pages available in the data source")]
		public string NavigatePreviousText
		{
			get { return navigatePreviousText; }
			set { navigatePreviousText = value; }
		}

		/// <summary>
		/// Gets or sets the text for the 'Next' link
		/// </summary>
		[Category("Appearance"), Description("Number of pages available in the data source")]
		public string NavigateNextText
		{
			get { return navigateNextText; }
			set { navigateNextText = value; }
		}

		/// <summary>
		/// Gets or sets the style attribute for the main table
		/// </summary>
		[Category("Appearance"), DefaultValue(""), Description("Number of pages available in the data source")]
		public string MainTableStyle
		{
			get { return mainTableStyle; }
			set { mainTableStyle = value; }
		}

		/// <summary>
		/// Gets or sets the location of SmartPager.js
		/// </summary>
		[Category("Misc"), DefaultValue(null), Description("Location of SmartPager.js")]
		public string ScriptPath
		{
			get { return scriptPath; }
			set { scriptPath = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether to output the first and last page links
		/// </summary>
		[Category("Appearance"), Description("Determines whether to output the first and last page links")]
		public bool OutputFirstAndLastLinks
		{
			get { return outputFirstAndLastLinks; }
			set { outputFirstAndLastLinks = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether clicking the ellipses should display the Go-to-page layer
		/// </summary>
		[Category("Behavior"), Description("Determines whether clicking the ellipses should display the Go-to-page layer")]
		public bool EnableGoToPage
		{
			get { return enableGoToPage; }
			set { enableGoToPage = value; }
		}

		/// <summary>
		/// Gets or sets the font size for page links
		/// </summary>
		[Category("Appearance")]
		public string FontSize
		{
			get { return fontSize; }
			set { fontSize = value; }
		}

		/// <summary>
		/// Gets or sets the color for page links
		/// </summary>
		[Category("Appearance")]
		public string PageLinkForeColor
		{
			get { return pageLinkForeColor; }
			set { pageLinkForeColor = value; }
		}

		/// <summary>
		/// Gets or sets the background color for page links
		/// </summary>
		[Category("Appearance")]
		public string PageLinkBackColor
		{
			get { return pageLinkBackColor; }
			set { pageLinkBackColor = value; }
		}

		/// <summary>
		/// Gets or sets the hover color for page links
		/// </summary>
		[Category("Appearance")]
		public string PageLinkHoverForeColor
		{
			get { return pageLinkHoverForeColor; }
			set { pageLinkHoverForeColor = value; }
		}

		/// <summary>
		/// Gets or sets the hover background color for page links
		/// </summary>
		[Category("Appearance")]
		public string PageLinkHoverBackColor
		{
			get { return pageLinkHoverBackColor; }
			set { pageLinkHoverBackColor = value; }
		}

		/// <summary>
		/// Gets or sets the color for selected page links
		/// </summary>
		[Category("Appearance")]
		public string PageLinkSelectedForeColor
		{
			get { return pageLinkSelectedForeColor; }
			set { pageLinkSelectedForeColor = value; }
		}

		/// <summary>
		/// Gets or sets the background color for selected page links
		/// </summary>
		[Category("Appearance")]
		public string PageLinkSelectedBackColor
		{
			get { return pageLinkSelectedBackColor; }
			set { pageLinkSelectedBackColor = value; }
		}

		/// <summary>
		/// Gets or sets the amount of padding in pixels of page number boxes
		/// </summary>
		[Category("Appearance")]
		public int PageNumberBoxPadding
		{
			get { return pageNumberBoxPadding; }
			set { pageNumberBoxPadding = value; }
		}

		/// <summary>
		/// Gets or sets the border width in pixels of page number boxes
		/// </summary>
		[Category("Appearance")]
		public int PageNumberBoxBorderWidth
		{
			get { return pageNumberBoxBorderWidth; }
			set { pageNumberBoxBorderWidth = value; }
		}

		/// <summary>
		/// Gets or sets the border color of page number boxes
		/// </summary>
		[Category("Appearance")]
		public string PageNumberBoxBorderColor
		{
			get { return pageNumberBoxBorderColor; }
			set { pageNumberBoxBorderColor = value; }
		}

		/// <summary>
		/// Gets or sets the text to indicate page numbers that are omitted
		/// </summary>
		[Category("Appearance")]
		public string EllipsisText
		{
			get { return ellipsisText; }
			set { ellipsisText = value; }
		}

		/// <summary>
		/// Gets or sets the name of the JavaScript function to handle the page-change (overriding the default Postback behavior)
		/// </summary>
		[Category("Behavior"), Description("Specify a JS function to handle the page-change (overriding the default Postback behavior)")]
		public string ClientPageChanged
		{
			get { return clientPageChanged; }
			set { clientPageChanged = value; }
		}

		/// <summary>
		/// Gets or sets the text for the textbox-label on the Go-to-page layer
		/// </summary>
		[Category("Appearance")]
		public string PageLabelText
		{
			get { return pageLabelText; }
			set { pageLabelText = value; }
		}

		/// <summary>
		/// Gets or sets the text for the GO button on the Go-to-page layer
		/// </summary>
		[Category("Appearance")]
		public string GoButtonText
		{
			get { return goButtonText; }
			set { goButtonText = value; }
		}
		#endregion


		#region Public Events
		/// <summary>
		/// Occurs when the user navigates to a page on this control
		/// </summary>
		public event EventHandler PageChanged;
		#endregion


		#region Private Members
		private int display = 9;
		private int pageCount = 20;
		private int currentPage = 1;
		private bool outputNextPrevLinks = true;
		private string fontSize = null;
		private bool enableGoToPage = true;
		private bool outputFirstAndLastLinks = true;
		private string scriptPath = "";
		private string mainTableStyle = "";
		private string navigateNextText = "Next &#187;";
		private string navigatePreviousText = "&#171; Previous";
		private string disabledNextPrevStyle = "display:none";
		private string pageLinkForeColor = null;
		private string pageLinkBackColor = null;
		private string pageLinkHoverForeColor = null;
		private string pageLinkHoverBackColor = null;
		private string pageLinkSelectedForeColor = "red";
		private string pageLinkSelectedBackColor = null;
		private int pageNumberBoxPadding = 5;
		private int pageNumberBoxBorderWidth = 1;
		private string pageNumberBoxBorderColor = "#ccc";
		private string ellipsisText = " &#133; ";
		private string clientPageChanged = null;
		private string pageLabelText = "Page:";
		private string goButtonText = "GO";

		private string[] tooltips = null;
		#endregion



		protected override void OnInit(EventArgs e)
		{
			this.Load += new EventHandler(SmartPager_Load);
            base.OnInit(e);
		}

       


		private void SmartPager_Load(object sender, EventArgs e)
		{
#if CLR_v1
            Page.RegisterClientScriptBlock("SmartPager_js", "<script language=JavaScript src=\"" + scriptPath + "SmartPager.js\"></script>");
			Page.RegisterClientScriptBlock("SmartPager_js2", string.Format("<script language=JavaScript>document.getElementById('smartPagerPageLabel').innerHTML='{0}'; document.getElementById('smartPagerGoLabel').innerHTML='{1}'</script>", pageLabelText, goButtonText));
#else
			bool foundRsrc = false;
			foreach (string rsrcName in this.GetType().Assembly.GetManifestResourceNames())
			{
				if (rsrcName.EndsWith(".SmartPager.js"))
				{
					foundRsrc = true;
					break;
				}
			}
			string scriptUrl = (foundRsrc) ? Page.ClientScript.GetWebResourceUrl(this.GetType(), "Avg.Controls.SmartPager.js") : scriptPath + "SmartPager.js";
			Page.ClientScript.RegisterClientScriptInclude("SmartPager_js", scriptUrl);
			
			Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "SmartPager_js2", string.Format("<script language=JavaScript>document.getElementById('smartPagerPageLabel').innerHTML='{0}'; document.getElementById('smartPagerGoLabel').innerHTML='{1}'</script>", pageLabelText, goButtonText));
#endif


            //handle Ajax Call back 
            string ReferenceVersFonctionClienteInitiatriceDuCallBack = Page.ClientScript.GetCallbackEventReference(this, "arg", "FunctionCallBack", "context", "FunctionCallBackError", false);
            string ScriptFonctionCliente = "function ExecuteCallBack(arg,context){" + ReferenceVersFonctionClienteInitiatriceDuCallBack + ";}";
            Page.ClientScript.RegisterClientScriptBlock(
                this.GetType(),
                "callback",
                ScriptFonctionCliente,
                true);
		}


		protected override void Render(HtmlTextWriter writer)
		{
			if (PageCount <= 1)
				Display = -1;

			int[] links;

			if (Display == -1)
			{
				links = new int[PageCount];
				for (int i = 0; i < links.Length; i++)
					links[i] = i + 1;
			}
			else
			{
				links = new int[Display];

				// current page in the middle of our range
				int middle = (int)Math.Ceiling(Display / 2.0) - 1;
				links[middle] = currentPage;

				// pages preceding current page
				for (int i = middle - 1; i >= 0; i--)
					links[i] = links[i + 1] - 1;

				// pages following current page
				for (int i = middle + 1; i < links.Length; i++)
					links[i] = links[i - 1] + 1;


				// Get rid of page numbers exceeding PageCount ("shift" page numbers to the right)
				while (links[links.Length - 1] > PageCount)
				{
					for (int i = 0; i < links.Length; i++)
						links[i]--;
				}

				// Get rid of 0 or negative pages ("shift" page numbers to the left)
				while (links[0] <= 0)
				{
					for (int i = 0; i < links.Length; i++)
						links[i]++;
				}

				// assign -1 to pages over PageCount
				for (int i = links.Length - 1; i >= 0; i--)
				{
					if (links[i] > PageCount)
						links[i] = -1;
					else
						break;
				}
			}


			// javascript tooltips array
			StringBuilder tooltipsJsArr = new StringBuilder();
			if (tooltips != null)
			{
				foreach (string s in tooltips)
					tooltipsJsArr.AppendFormat("\"{0}\",", Page.Server.HtmlEncode(s));
				if (tooltipsJsArr.Length > 0)
					tooltipsJsArr.Remove(tooltipsJsArr.Length - 1, 1);
			}


			// ** HTML output begins **

			// JS variables for go-to-page popup
			writer.WriteLine("<script>var {0}$pagerPageCount = {1}; var {0}$tooltipsArr = [{2}]; var {0}$callJS = '{3}'</script>", ClientID, PageCount, tooltipsJsArr, clientPageChanged);


			// CSS
			string userAgent = "MSIE";
			try 
			{
				userAgent = Page.Request.UserAgent; // VS designer doesn't have a Request
			}
			catch { }
			string MsIEOnly = (userAgent != null && userAgent.IndexOf("MSIE") != -1) ? "background-color:{2};" : "";

			writer.WriteLine("<style type=text/css>");
			writer.WriteLine("a.pagerLink_{0} {{ color:{1}; text-decoration:none; font-size:{3}; }}", this.ClientID, pageLinkForeColor, pageLinkBackColor, fontSize);  // background-color:{2}; 
			writer.WriteLine("a.pagerLink_{0} span {{ background-color:{1}; }}", this.ClientID, pageLinkBackColor);
			writer.WriteLine("a.pagerLink_{0}:hover {{ color:{1}; " + MsIEOnly + "}}", this.ClientID, pageLinkHoverForeColor, pageLinkHoverBackColor);
			writer.WriteLine("a.pagerLink_{0}:hover span {{ background-color:{1}; }}", this.ClientID, pageLinkSelectedBackColor); // This has no effect in IE
			writer.WriteLine("a.pagerLinkSel_{0} {{ color:{1}; text-decoration:none; font-weight:bold; font-size:{3}; }}", this.ClientID, pageLinkSelectedForeColor, pageLinkSelectedBackColor, fontSize); // background-color:{2}; 
			writer.WriteLine("a.pagerLinkSel_{0} span {{ background-color:{1}; }}", this.ClientID, pageLinkSelectedBackColor);
			writer.WriteLine("span.pagerPageNo_{0} {{ height:1; cursor:hand; padding:{1}px; margin-left:2px; margin-right:2px; border:{2}px solid {3}; }}", this.ClientID, pageNumberBoxPadding, pageNumberBoxBorderWidth, pageNumberBoxBorderColor);
			writer.WriteLine("</style>");


			// main table
			writer.WriteLine("<table border=0 cellpadding=0 cellspacing=0 style=\"" + mainTableStyle + "\"><tr>");


			if (outputNextPrevLinks)
			{
				// previous link
				writer.Write("<td nowrap><nobr>");
				if (currentPage > 1)
					writer.Write("<a href=\"javascript:SmartPagerSelectPage('{0}', '{1}')\" class=pagerLink_{0} title=\"{2}\">&#171; Previous</a> &nbsp;", ClientID, currentPage - 1, getTooltipText(currentPage - 2));
				else
					writer.Write("<div style=\"{0}\">{1} &nbsp;</div>", disabledNextPrevStyle, navigatePreviousText);
				writer.WriteLine("</nobr></td>");
			}


			// page numbers
			writer.Write("<td align=center style='padding:3 0 3 0'>");


			if (links[0] != 1)
			{
				if (outputFirstAndLastLinks)
					// output link to first page number
					writer.Write("<a href=\"javascript:SmartPagerSelectPage('{0}', '{1}')\" class={2}_{0} title=\"{3}\"><span class=pagerPageNo_{0}>{1}</span></a>", ClientID, 1, (1 == currentPage) ? "pagerLinkSel" : "pagerLink", getTooltipText(0));

				if (links[0] != 2)
				{
					// output ellipsis
					if (enableGoToPage)
						writer.Write("<a href=# onclick=\"SmartPagerID='{0}';showPager(this);return false\" class=pagerLink_{0} style='position:relative;background-color:transparent;'>{1}</a>", ClientID, ellipsisText);
					else
						writer.Write(ellipsisText);
				}
			}


			// output page number links
			for (int i = 0; i < links.Length; i++)
			{
				if (links[i] == -1)
					break;

				writer.WriteLine("<a href=\"javascript:SmartPagerSelectPage('{0}', '{1}')\" class={2}_{0} title=\"{3}\"><span class=pagerPageNo_{0}>{1}</span></a", ClientID, links[i], (links[i] == currentPage) ? "pagerLinkSel" : "pagerLink", getTooltipText(links[i] - 1));
				writer.Write(">"); // span the </a> tag accross two lines so no line break between tags in HTML

				if (Display == -1)
					writer.Write(" "); // write a space so page numbers can wrap if displaying ALL page links
			}


			if (links[links.Length - 1] != -1 && links[links.Length - 1] != PageCount)
			{
				if (links[links.Length - 1] != PageCount - 1)
				{
					// output ellipsis
					if (enableGoToPage)
						writer.Write("<a href=#o onclick=\"SmartPagerID='{0}';showPager(this);return false\" class=pagerLink_{0} style='position:relative;background-color:transparent;'>{1}</a>", ClientID, ellipsisText);
					else
						writer.Write(ellipsisText);
				}

				if (outputFirstAndLastLinks)
					// output link to last page number
					writer.Write("<a href=\"javascript:SmartPagerSelectPage('{0}', '{1}')\" class={2}_{0} title=\"{3}\"><span class=pagerPageNo_{0}>{1}</span></a>", ClientID, PageCount, (PageCount == currentPage) ? "pagerLinkSel" : "pagerLink", getTooltipText(PageCount - 1));
			}
			writer.WriteLine("</div></td>");


			if (outputNextPrevLinks)
			{
				// next link
				writer.Write("<td nowrap align=right><nobr>");
				if (currentPage < PageCount)
					writer.Write("&nbsp; <a href=\"javascript:SmartPagerSelectPage('{0}', '{1}')\" class=pagerLink_{0} title=\"{2}\">Next &#187;</a>", ClientID, currentPage + 1, getTooltipText(currentPage));
				else
					writer.Write("<div style=\"{0}\">&nbsp; {1}</div>", disabledNextPrevStyle, navigateNextText);
				writer.WriteLine("</nobr></td>");
			}

			writer.WriteLine("</tr></table>");

			writer.WriteLine("<input type=hidden name='{0}' id='hdn{1}'>", UniqueID, ClientID);
		}


		// Check postback data (IPostBackDataHandler required method)
		public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
		{
			// get the previously selected page from the viewstate
			if (ViewState[ClientID + "_CurrentPage"] != null)
				currentPage = Convert.ToInt32(ViewState[ClientID + "_CurrentPage"]);

			bool changed = (postCollection[postDataKey] != "");
			if (changed)
				CurrentPage = Convert.ToInt32(postCollection[postDataKey]);

			return changed;
		}


		// Raise the PageChanged event (IPostBackDataHandler required method)
		public virtual void RaisePostDataChangedEvent()
		{
			OnPageChanged(EventArgs.Empty);
		}


		protected virtual void OnPageChanged(EventArgs e)
		{
			if (PageChanged != null)
				PageChanged(this, e);
		}


		/// <summary>
		/// Specify the tooltips for the page numbers
		/// </summary>
		/// <param name="tooltips">String array of tooltip values</param>
		public void SetTooltips(string[] tooltips)
		{
			this.tooltips = new string[PageCount];
			Array.Copy(tooltips, 0, this.tooltips, 0, tooltips.Length);
		}


		private string getTooltipText(int index)
		{
			if (tooltips == null)
				return "";
			else
				return Page.Server.HtmlEncode(tooltips[index]);
		}


		/// <summary>
		/// Clones the urrent instance of the control
		/// </summary>
		/// <returns>Clone of this control instance</returns>
		public object Clone()
		{
			SmartPager inst = new SmartPager();

			inst.display = display;
			inst.pageCount = pageCount;
			inst.currentPage = currentPage;
			inst.scriptPath = scriptPath;
			inst.mainTableStyle = mainTableStyle;
			inst.outputNextPrevLinks = outputNextPrevLinks;
			inst.navigatePreviousText = navigatePreviousText;
			inst.navigateNextText = navigateNextText;
			inst.outputFirstAndLastLinks = outputFirstAndLastLinks;
			inst.enableGoToPage = enableGoToPage;
			inst.fontSize = fontSize;
			inst.pageLinkForeColor = pageLinkForeColor;
			inst.pageLinkBackColor = pageLinkBackColor;
			inst.pageLinkHoverForeColor = pageLinkHoverForeColor;
			inst.pageLinkHoverBackColor = pageLinkHoverBackColor;
			inst.pageLinkSelectedForeColor = pageLinkSelectedForeColor;
			inst.pageLinkSelectedBackColor = pageLinkSelectedBackColor;
			inst.pageNumberBoxPadding = pageNumberBoxPadding;
			inst.pageNumberBoxBorderWidth = pageNumberBoxBorderWidth;
			inst.pageNumberBoxBorderColor = pageNumberBoxBorderColor;
			inst.ellipsisText = ellipsisText;
			inst.disabledNextPrevStyle = disabledNextPrevStyle;
			inst.tooltips = tooltips;

			return inst;
		}

        #region ICallbackEventHandler Members

        public string GetCallbackResult()
        {
            return "";
        }

        public void RaiseCallbackEvent(string eventArgument)
        {
            if (OnClickEvent != null)
            {
                OnClickEvent(
                    this, 
                    eventArgument
                 );
                
            }
        }

        #endregion

        #region IStateManager Members


        private StateBag viewState;
        protected virtual StateBag ViewState
        {
            get
            {
                if (viewState == null)
                {
                    viewState = new StateBag();
                    if (IsTrackingViewState)
                        ((IStateManager)viewState).TrackViewState();
                }
                return viewState;
            }
        }

        private bool isTrackingViewState;
        public new bool IsTrackingViewState
        {
            get { return isTrackingViewState; }
        }

        public void LoadViewState(object savedState)
        {
            if (savedState != null)
                ((IStateManager)ViewState).LoadViewState(savedState);
        }

        public object SaveViewState()
        {
            if (viewState != null)
                return ((IStateManager)ViewState).SaveViewState();
            return null;
        }

        public void TrackViewState()
        {
            isTrackingViewState = true;
            if (viewState != null)
                ((IStateManager)ViewState).TrackViewState();
        }

        #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 Several
France France
Fan of .NET Technologies
Go to see my blog : http://davidzenou.blogspot.com/2009/01/david.html

Comments and Discussions