Since listview control in .net framework 2.0 does not have a datasource property, it is not bindable to neither datatable nor generic lists. i created a derived custom listview that is bindable to lists of any type. i attach the .zip to this thread.
I dedicate this custom windows control to Julienne Walker.

SmartListView.cs :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;

namespace SmartListView
{
	public partial class SmartListView : ListView
	{
		public SmartListView()
		{
			InitializeComponent();
		}

		
		private IList dataSource = null;
		
		public IList DataSource
		{
			get
			{
				return dataSource;
			}
			set
			{
				dataSource = value;
				if(dataSource != null)
					CreateItems();
			}
		}

		private string[] columnHeaders = null;
		public string[] ColumnHeaders
		{
			set
			{
				columnHeaders = value;
			}
		}

		private void CreateItems()
		{
			
			if (dataSource.Count > 0)
			{

				PropertyInfo[] properties = dataSource[0].GetType().GetProperties();
				if(properties.Length > 0)
				{
					if (columnHeaders != null)
					{
						foreach (string columnName in columnHeaders)
						{
							Columns.Add(columnName);
						}
					}
					else
					{

						foreach (PropertyInfo pInfo in properties)
						{
							Columns.Add(pInfo.Name);
						}
					}
					for (int i = 0; i < dataSource.Count; i++)
					{
						ListViewItem lvi = new ListViewItem();
						lvi.Text = properties[0].GetValue(dataSource[i],null).ToString();
						for (int propIndex = 1; propIndex < properties.Length;propIndex++)
						{
							lvi.SubItems.Add(properties[propIndex].GetValue(dataSource[i], null).ToString());
						}
						Items.Add(lvi);
					}
				}
			}
		}

	}
}

SmartListView.Designer.cs :

namespace SmartListView
{
	partial class SmartListView
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Component Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			components = new System.ComponentModel.Container();
			this.View = System.Windows.Forms.View.Details;
		}

		#endregion
	}
}
kvprajapati commented: Informative thread. +7
sknake commented: informative +4

i combined the code to make it sortable from microsoft :

http://support.microsoft.com/kb/319401

now it became more smarter and is sortable. i again attach the solution. And again dedicate this post to Julienne Walker.

SmartListView.cs :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;

namespace SmartListView
{
	public partial class SmartListView : ListView
	{
		public SmartListView()
		{
			InitializeComponent();
		}

		
		private IList dataSource = null;
		
		public IList DataSource
		{
			get
			{
				return dataSource;
			}
			set
			{
				dataSource = value;
				if (dataSource != null)
				{
					try
					{
						CreateItems();
					}
					catch (Exception ex)
					{
						MessageBox.Show(ex.Message);
					}
				}
			}
		}

		private string[] columnHeaders = null;
		public string[] ColumnHeaders
		{
			set
			{
				columnHeaders = value;
			}
		}

		private void CreateItems()
		{
			
			if (dataSource.Count > 0)
			{

				PropertyInfo[] properties = dataSource[0].GetType().GetProperties();
				if(properties.Length > 0)
				{
					if (columnHeaders != null)
					{
						if (columnHeaders.Length == properties.Length)
						{
							foreach (string columnName in columnHeaders)
							{
								Columns.Add(columnName);
							}
						}
						else
						{
							throw new ApplicationException("Column header collection does not match object properties");
						}
					}
					else
					{

						foreach (PropertyInfo pInfo in properties)
						{
							Columns.Add(pInfo.Name);
						}
					}
					for (int i = 0; i < dataSource.Count; i++)
					{
						ListViewItem lvi = new ListViewItem();
						lvi.Text = properties[0].GetValue(dataSource[i],null).ToString();
						for (int propIndex = 1; propIndex < properties.Length;propIndex++)
						{
							lvi.SubItems.Add(properties[propIndex].GetValue(dataSource[i], null).ToString());
						}
						Items.Add(lvi);
					}
				}
			}
		}

		#region Sorting Functionality

		private ListViewColumnSorter lvwColumnSorter;

		/// <summary>
		/// This class is an implementation of the 'IComparer' interface.
		/// </summary>
		public class ListViewColumnSorter : IComparer
		{
			/// <summary>
			/// Specifies the column to be sorted
			/// </summary>
			private int ColumnToSort;
			/// <summary>
			/// Specifies the order in which to sort (i.e. 'Ascending').
			/// </summary>
			private SortOrder OrderOfSort;
			/// <summary>
			/// Case insensitive comparer object
			/// </summary>
			private CaseInsensitiveComparer ObjectCompare;

			/// <summary>
			/// Class constructor.  Initializes various elements
			/// </summary>
			public ListViewColumnSorter()
			{
				// Initialize the column to '0'
				ColumnToSort = 0;

				// Initialize the sort order to 'none'
				OrderOfSort = SortOrder.None;

				// Initialize the CaseInsensitiveComparer object
				ObjectCompare = new CaseInsensitiveComparer();
			}

			/// <summary>
			/// This method is inherited from the IComparer interface.  It compares the two objects passed using a case insensitive comparison.
			/// </summary>
			/// <param name="x">First object to be compared</param>
			/// <param name="y">Second object to be compared</param>
			/// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
			public int Compare(object x, object y)
			{
				int compareResult;
				ListViewItem listviewX, listviewY;

				// Cast the objects to be compared to ListViewItem objects
				listviewX = (ListViewItem)x;
				listviewY = (ListViewItem)y;

				// Compare the two items
				compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text);

				// Calculate correct return value based on object comparison
				if (OrderOfSort == SortOrder.Ascending)
				{
					// Ascending sort is selected, return normal result of compare operation
					return compareResult;
				}
				else if (OrderOfSort == SortOrder.Descending)
				{
					// Descending sort is selected, return negative result of compare operation
					return (-compareResult);
				}
				else
				{
					// Return '0' to indicate they are equal
					return 0;
				}
			}

			/// <summary>
			/// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0').
			/// </summary>
			public int SortColumn
			{
				set
				{
					ColumnToSort = value;
				}
				get
				{
					return ColumnToSort;
				}
			}

			/// <summary>
			/// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending').
			/// </summary>
			public SortOrder Order
			{
				set
				{
					OrderOfSort = value;
				}
				get
				{
					return OrderOfSort;
				}
			}

		}
		private void SmartListView_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
		{
			// Determine if clicked column is already the column that is being sorted.
			if (e.Column == lvwColumnSorter.SortColumn)
			{
				// Reverse the current sort direction for this column.
				if (lvwColumnSorter.Order == SortOrder.Ascending)
				{
					lvwColumnSorter.Order = SortOrder.Descending;
				}
				else
				{
					lvwColumnSorter.Order = SortOrder.Ascending;
				}
			}
			else
			{
				// Set the column number that is to be sorted; default to ascending.
				lvwColumnSorter.SortColumn = e.Column;
				lvwColumnSorter.Order = SortOrder.Ascending;
			}

			// Perform the sort with these new sort options.
			this.Sort();

		}
		#endregion

	}
}

SmartListView.Designer.cs :

namespace SmartListView
{
	partial class SmartListView
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Component Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			components = new System.ComponentModel.Container();
			this.View = System.Windows.Forms.View.Details;
			this.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(SmartListView_ColumnClick);
			// Create an instance of a ListView column sorter and assign it 
			// to the ListView control.
			lvwColumnSorter = new ListViewColumnSorter();
			this.ListViewItemSorter = lvwColumnSorter;
		}

		

		#endregion
	}
}

it now has one more public property to display or hide item number column.

SmartListView.cs :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;

namespace SmartListView
{
	public partial class SmartListView : ListView
	{
		#region Constructor

		public SmartListView()
		{
			InitializeComponent();
		}

		#endregion

		#region Properties

		private IList dataSource = null;
		
		public IList DataSource
		{
			get
			{
				return dataSource;
			}
			set
			{
				dataSource = value;
				if (dataSource != null)
				{
					try
					{
						CreateItems();
					}
					catch (Exception ex)
					{
						MessageBox.Show(ex.Message);
					}
				}
			}
		}

		private string[] columnHeaders = null;
		public string[] ColumnHeaders
		{
			set
			{
				columnHeaders = value;
			}
		}

		private bool showNumberColumn = true;

		public bool ShowNumberColumn
		{
			get { return showNumberColumn; }
			set { showNumberColumn = value; }
		}

		#endregion

		#region Helper Methods

		private void CreateItems()
		{
			Items.Clear();
			Columns.Clear();
			if (dataSource.Count > 0)
			{

				PropertyInfo[] properties = dataSource[0].GetType().GetProperties();
				if(properties.Length > 0)
				{
					if (columnHeaders != null)
					{
						if (columnHeaders.Length == properties.Length)
						{
							foreach (string columnName in columnHeaders)
							{
								Columns.Add(columnName);
							}
						}
						else
						{
							throw new ApplicationException("Column header collection does not match object properties");
						}
					}
					else
					{

						foreach (PropertyInfo pInfo in properties)
						{
							Columns.Add(pInfo.Name);
						}
					}

					if (showNumberColumn)
					{
						ColumnHeader ch = new ColumnHeader();
						ch.Width = -2;
						ch.Text = "#";
						Columns.Insert(0,ch);
						for (int i = 0; i < dataSource.Count; i++)
						{
							ListViewItem lvi = new ListViewItem();
							lvi.Text = (i + 1).ToString();
							for (int propIndex=0; propIndex < properties.Length; propIndex++)
							{
								lvi.SubItems.Add(properties[propIndex].GetValue(dataSource[i], null).ToString());
							}
							Items.Add(lvi);
						}
					}
					else
					{
						for (int i = 0; i < dataSource.Count; i++)
						{
							ListViewItem lvi = new ListViewItem();
							lvi.Text = properties[0].GetValue(dataSource[i], null).ToString();
							for (int propIndex = 1; propIndex < properties.Length; propIndex++)
							{
								lvi.SubItems.Add(properties[propIndex].GetValue(dataSource[i], null).ToString());
							}
							Items.Add(lvi);
						}
					}

				}
			}
		}

		#endregion

		#region Sorting Functionality

		private ListViewColumnSorter lvwColumnSorter;

		/// <summary>
		/// This class is an implementation of the 'IComparer' interface.
		/// </summary>
		public class ListViewColumnSorter : IComparer
		{
			/// <summary>
			/// Specifies the column to be sorted
			/// </summary>
			private int ColumnToSort;
			/// <summary>
			/// Specifies the order in which to sort (i.e. 'Ascending').
			/// </summary>
			private SortOrder OrderOfSort;
			/// <summary>
			/// Case insensitive comparer object
			/// </summary>
			private CaseInsensitiveComparer ObjectCompare;

			/// <summary>
			/// Class constructor.  Initializes various elements
			/// </summary>
			public ListViewColumnSorter()
			{
				// Initialize the column to '0'
				ColumnToSort = 0;

				// Initialize the sort order to 'none'
				OrderOfSort = SortOrder.None;

				// Initialize the CaseInsensitiveComparer object
				ObjectCompare = new CaseInsensitiveComparer();
			}

			/// <summary>
			/// This method is inherited from the IComparer interface.  It compares the two objects passed using a case insensitive comparison.
			/// </summary>
			/// <param name="x">First object to be compared</param>
			/// <param name="y">Second object to be compared</param>
			/// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
			public int Compare(object x, object y)
			{
				int compareResult;
				ListViewItem listviewX, listviewY;

				// Cast the objects to be compared to ListViewItem objects
				listviewX = (ListViewItem)x;
				listviewY = (ListViewItem)y;

				// Compare the two items
				compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text);

				// Calculate correct return value based on object comparison
				if (OrderOfSort == SortOrder.Ascending)
				{
					// Ascending sort is selected, return normal result of compare operation
					return compareResult;
				}
				else if (OrderOfSort == SortOrder.Descending)
				{
					// Descending sort is selected, return negative result of compare operation
					return (-compareResult);
				}
				else
				{
					// Return '0' to indicate they are equal
					return 0;
				}
			}

			/// <summary>
			/// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0').
			/// </summary>
			public int SortColumn
			{
				set
				{
					ColumnToSort = value;
				}
				get
				{
					return ColumnToSort;
				}
			}

			/// <summary>
			/// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending').
			/// </summary>
			public SortOrder Order
			{
				set
				{
					OrderOfSort = value;
				}
				get
				{
					return OrderOfSort;
				}
			}

		}
		private void SmartListView_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
		{
			// Determine if clicked column is already the column that is being sorted.
			if (e.Column == lvwColumnSorter.SortColumn)
			{
				// Reverse the current sort direction for this column.
				if (lvwColumnSorter.Order == SortOrder.Ascending)
				{
					lvwColumnSorter.Order = SortOrder.Descending;
				}
				else
				{
					lvwColumnSorter.Order = SortOrder.Ascending;
				}
			}
			else
			{
				// Set the column number that is to be sorted; default to ascending.
				lvwColumnSorter.SortColumn = e.Column;
				lvwColumnSorter.Order = SortOrder.Ascending;
			}

			// Perform the sort with these new sort options.
			this.Sort();

		}
		#endregion

	}
}

SmartListView.Designer.cs :

namespace SmartListView
{
	partial class SmartListView
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Component Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			components = new System.ComponentModel.Container();
			this.View = System.Windows.Forms.View.Details;
			this.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(SmartListView_ColumnClick);
			// Create an instance of a ListView column sorter and assign it 
			// to the ListView control.
			lvwColumnSorter = new ListViewColumnSorter();
			this.ListViewItemSorter = lvwColumnSorter;
		}

		

		#endregion
	}
}

this is the tester form to use that SmartListView :

Form1.cs :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Tester
{
	public partial class Form1 : Form
	{
		public Form1()
		{
			InitializeComponent();
		}

		public class Programmer
		{
			string name = string.Empty;

			public string Name
			{
				get { return name; }
				set { name = value; }
			}
			string lastName = string.Empty;

			public string LastName
			{
				get { return lastName; }
				set { lastName = value; }
			}
		}
		List<Programmer> mylist = new List<Programmer>();
		private void button1_Click(object sender, EventArgs e)
		{
			

			Programmer p1 = new Programmer();
			p1.Name = "Julienne";
			p1.LastName = "Walker";
			Programmer p2 = new Programmer();
			p2.Name = "Serkan";
			p2.LastName = "Sendur";
			Programmer p3 = new Programmer();
			p3.Name = "Adatapost";
			p3.LastName = "Adatapost";
			Programmer p4 = new Programmer();
			p4.Name = "Scott";
			p4.LastName = "sknake";
			Programmer p5 = new Programmer();
			p5.Name = "Ramy";
			p5.LastName = "Rahmous";
			mylist.Add(p1);
			mylist.Add(p2);
			mylist.Add(p3);
			mylist.Add(p4);
			mylist.Add(p5);

			smartListView1.ColumnHeaders = new string[] {"Name","Last Name"};
			smartListView1.DataSource = mylist;
		}

		private void button2_Click(object sender, EventArgs e)
		{
			if (smartListView1.ShowNumberColumn == true)
				smartListView1.ShowNumberColumn = false;
			else
				smartListView1.ShowNumberColumn = true;
			smartListView1.DataSource = mylist;
		}
	}
}

Form1.Designer.cs :

namespace Tester
{
	partial class Form1
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.button1 = new System.Windows.Forms.Button();
			this.smartListView1 = new SmartListView.SmartListView();
			this.button2 = new System.Windows.Forms.Button();
			this.SuspendLayout();
			// 
			// button1
			// 
			this.button1.Location = new System.Drawing.Point(22, 149);
			this.button1.Name = "button1";
			this.button1.Size = new System.Drawing.Size(90, 23);
			this.button1.TabIndex = 1;
			this.button1.Text = "Populate";
			this.button1.UseVisualStyleBackColor = true;
			this.button1.Click += new System.EventHandler(this.button1_Click);
			// 
			// smartListView1
			// 
			this.smartListView1.DataSource = null;
			this.smartListView1.Location = new System.Drawing.Point(22, 26);
			this.smartListView1.Name = "smartListView1";
			this.smartListView1.ShowNumberColumn = true;
			this.smartListView1.Size = new System.Drawing.Size(245, 109);
			this.smartListView1.TabIndex = 2;
			this.smartListView1.UseCompatibleStateImageBehavior = false;
			this.smartListView1.View = System.Windows.Forms.View.Details;
			// 
			// button2
			// 
			this.button2.Location = new System.Drawing.Point(129, 149);
			this.button2.Name = "button2";
			this.button2.Size = new System.Drawing.Size(138, 23);
			this.button2.TabIndex = 3;
			this.button2.Text = "Toggle Number Column";
			this.button2.UseVisualStyleBackColor = true;
			this.button2.Click += new System.EventHandler(this.button2_Click);
			// 
			// Form1
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(292, 266);
			this.Controls.Add(this.button2);
			this.Controls.Add(this.smartListView1);
			this.Controls.Add(this.button1);
			this.Name = "Form1";
			this.Text = "Form1";
			this.ResumeLayout(false);

		}

		#endregion

		private System.Windows.Forms.Button button1;
		private SmartListView.SmartListView smartListView1;
		private System.Windows.Forms.Button button2;
	}
}

i noticed that the sorting treats every item as string. so when you try to sort the number column it puts 10 right after 1 thinking that it is a string. so i added an AllNumeric method to see if everything is a number then treat them as integer. I attach the latest version.

SmartListView.cs :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;
using System.Text.RegularExpressions;

namespace SmartListView
{
	public partial class SmartListView : ListView
	{
		#region Constructor

		public SmartListView()
		{
			InitializeComponent();
		}

		#endregion

		#region Properties

		private IList dataSource = null;
		
		public IList DataSource
		{
			get
			{
				return dataSource;
			}
			set
			{
				dataSource = value;
				if (dataSource != null)
				{
					try
					{
						CreateItems();
					}
					catch (Exception ex)
					{
						MessageBox.Show(ex.Message);
					}
				}
			}
		}

		private string[] columnHeaders = null;
		public string[] ColumnHeaders
		{
			set
			{
				columnHeaders = value;
			}
		}

		private bool showNumberColumn = true;

		public bool ShowNumberColumn
		{
			get { return showNumberColumn; }
			set { showNumberColumn = value; }
		}

		#endregion

		#region Helper Methods

		private void CreateItems()
		{
			Items.Clear();
			Columns.Clear();
			if (dataSource.Count > 0)
			{

				PropertyInfo[] properties = dataSource[0].GetType().GetProperties();
				if(properties.Length > 0)
				{
					if (columnHeaders != null)
					{
						if (columnHeaders.Length == properties.Length)
						{
							foreach (string columnName in columnHeaders)
							{
								Columns.Add(columnName);
							}
						}
						else
						{
							throw new ApplicationException("Column header collection does not match object properties");
						}
					}
					else
					{

						foreach (PropertyInfo pInfo in properties)
						{
							Columns.Add(pInfo.Name);
						}
					}

					if (showNumberColumn)
					{
						ColumnHeader ch = new ColumnHeader();
						ch.Width = -2;
						ch.Text = "#";
						Columns.Insert(0,ch);
						for (int i = 0; i < dataSource.Count; i++)
						{
							ListViewItem lvi = new ListViewItem();
							lvi.Text = (i + 1).ToString();
							for (int propIndex=0; propIndex < properties.Length; propIndex++)
							{
								lvi.SubItems.Add(properties[propIndex].GetValue(dataSource[i], null).ToString());
							}
							Items.Add(lvi);
						}
					}
					else
					{
						for (int i = 0; i < dataSource.Count; i++)
						{
							ListViewItem lvi = new ListViewItem();
							lvi.Text = properties[0].GetValue(dataSource[i], null).ToString();
							for (int propIndex = 1; propIndex < properties.Length; propIndex++)
							{
								lvi.SubItems.Add(properties[propIndex].GetValue(dataSource[i], null).ToString());
							}
							Items.Add(lvi);
						}
					}

				}
			}
		}

		#region IsNumeric

		const string ALL_NUMERIC_PATTERN = "[a-z|A-Z]";

		static readonly Regex All_Numeric_Regex =
			new Regex(ALL_NUMERIC_PATTERN);

		static bool AllNumeric(string inputString)
		{
			if (All_Numeric_Regex.IsMatch(inputString))
			{
				return false;
			}
			return true;
		}

		#endregion

		#endregion

		#region Sorting Functionality

		private ListViewColumnSorter lvwColumnSorter;

		/// <summary>
		/// This class is an implementation of the 'IComparer' interface.
		/// </summary>
		public class ListViewColumnSorter : IComparer
		{
			/// <summary>
			/// Specifies the column to be sorted
			/// </summary>
			private int ColumnToSort;
			/// <summary>
			/// Specifies the order in which to sort (i.e. 'Ascending').
			/// </summary>
			private SortOrder OrderOfSort;
			/// <summary>
			/// Case insensitive comparer object
			/// </summary>
			private CaseInsensitiveComparer ObjectCompare;

			/// <summary>
			/// Class constructor.  Initializes various elements
			/// </summary>
			public ListViewColumnSorter()
			{
				// Initialize the column to '0'
				ColumnToSort = 0;

				// Initialize the sort order to 'none'
				OrderOfSort = SortOrder.None;

				// Initialize the CaseInsensitiveComparer object
				ObjectCompare = new CaseInsensitiveComparer();
			}

			/// <summary>
			/// This method is inherited from the IComparer interface.  It compares the two objects passed using a case insensitive comparison.
			/// </summary>
			/// <param name="x">First object to be compared</param>
			/// <param name="y">Second object to be compared</param>
			/// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
			public int Compare(object x, object y)
			{
				int compareResult;
				ListViewItem listviewX, listviewY;

				// Cast the objects to be compared to ListViewItem objects
				listviewX = (ListViewItem)x;
				listviewY = (ListViewItem)y;

				// Compare the two items
				if (AllNumeric(listviewX.SubItems[ColumnToSort].Text) && AllNumeric(listviewY.SubItems[ColumnToSort].Text))
				{
					compareResult = ObjectCompare.Compare(Convert.ToInt32(listviewX.SubItems[ColumnToSort].Text),Convert.ToInt32(listviewY.SubItems[ColumnToSort].Text));
				}
				else
				{
					compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text);
				}

				// Calculate correct return value based on object comparison
				if (OrderOfSort == SortOrder.Ascending)
				{
					// Ascending sort is selected, return normal result of compare operation
					return compareResult;
				}
				else if (OrderOfSort == SortOrder.Descending)
				{
					// Descending sort is selected, return negative result of compare operation
					return (-compareResult);
				}
				else
				{
					// Return '0' to indicate they are equal
					return 0;
				}
			}

			/// <summary>
			/// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0').
			/// </summary>
			public int SortColumn
			{
				set
				{
					ColumnToSort = value;
				}
				get
				{
					return ColumnToSort;
				}
			}

			/// <summary>
			/// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending').
			/// </summary>
			public SortOrder Order
			{
				set
				{
					OrderOfSort = value;
				}
				get
				{
					return OrderOfSort;
				}
			}

		}
		private void SmartListView_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
		{
			// Determine if clicked column is already the column that is being sorted.
			if (e.Column == lvwColumnSorter.SortColumn)
			{
				// Reverse the current sort direction for this column.
				if (lvwColumnSorter.Order == SortOrder.Ascending)
				{
					lvwColumnSorter.Order = SortOrder.Descending;
				}
				else
				{
					lvwColumnSorter.Order = SortOrder.Ascending;
				}
			}
			else
			{
				// Set the column number that is to be sorted; default to ascending.
				lvwColumnSorter.SortColumn = e.Column;
				lvwColumnSorter.Order = SortOrder.Ascending;
			}

			// Perform the sort with these new sort options.
			this.Sort();

		}
		#endregion

	}
}

i found a bug and modified the code, the final version of the project is attached.

SmartListView.cs :

#region Name Spaces

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;
using System.Text.RegularExpressions;

#endregion

namespace SmartListView
{
	public partial class SmartListView : ListView
	{
		#region Constructor

		public SmartListView()
		{
			InitializeComponent();
		}

		#endregion

		#region Properties

		private IList dataSource = null;
		
		public IList DataSource
		{
			get
			{
				return dataSource;
			}
			set
			{
				dataSource = value;
				if (dataSource != null)
				{
					try
					{
						CreateItems();
					}
					catch (Exception ex)
					{
						MessageBox.Show(ex.Message);
					}
				}
			}
		}

		private string[] columnHeaders = null;
		public string[] ColumnHeaders
		{
			set
			{
				columnHeaders = value;
			}
		}

		#endregion

		#region Helper Methods

		private void CreateItems()
		{
			Items.Clear();
			Columns.Clear();
			if (dataSource.Count > 0)
			{

				PropertyInfo[] properties = dataSource[0].GetType().GetProperties();
				if(properties.Length > 0)
				{
					if (columnHeaders != null)
					{
						if (columnHeaders.Length == properties.Length)
						{
							foreach (string columnName in columnHeaders)
							{
								Columns.Add(columnName);
							}
						}
						else
						{
							throw new ApplicationException("Column header collection does not match object properties");
						}
					}
					else
					{

						foreach (PropertyInfo pInfo in properties)
						{
							Columns.Add(pInfo.Name);
						}
					}

					ColumnHeader ch = new ColumnHeader();
					ch.Width = -2;
					ch.Text = "#";
					Columns.Insert(0,ch);
					for (int i = 0; i < dataSource.Count; i++)
					{
						ListViewItem lvi = new ListViewItem();
						lvi.Text = (i + 1).ToString();
						for (int propIndex=0; propIndex < properties.Length; propIndex++)
						{
							lvi.SubItems.Add(properties[propIndex].GetValue(dataSource[i], null).ToString());
						}
						Items.Add(lvi);
					}

				}
			}
		}

		#region IsNumeric

		const string ALL_NUMERIC_PATTERN = "[a-z|A-Z]";

		static readonly Regex All_Numeric_Regex =
			new Regex(ALL_NUMERIC_PATTERN);

		static bool AllNumeric(string inputString)
		{
			if (All_Numeric_Regex.IsMatch(inputString))
			{
				return false;
			}
			return true;
		}

		#endregion

		#endregion

		#region Sorting Functionality

		private ListViewColumnSorter lvwColumnSorter;

		/// <summary>
		/// This class is an implementation of the 'IComparer' interface.
		/// </summary>
		public class ListViewColumnSorter : IComparer
		{
			/// <summary>
			/// Specifies the column to be sorted
			/// </summary>
			private int ColumnToSort;
			/// <summary>
			/// Specifies the order in which to sort (i.e. 'Ascending').
			/// </summary>
			private SortOrder OrderOfSort;
			/// <summary>
			/// Case insensitive comparer object
			/// </summary>
			private CaseInsensitiveComparer ObjectCompare;

			/// <summary>
			/// Class constructor.  Initializes various elements
			/// </summary>
			public ListViewColumnSorter()
			{
				// Initialize the column to '0'
				ColumnToSort = 0;

				// Initialize the sort order to 'none'
				OrderOfSort = SortOrder.None;

				// Initialize the CaseInsensitiveComparer object
				ObjectCompare = new CaseInsensitiveComparer();
			}

			/// <summary>
			/// This method is inherited from the IComparer interface.  It compares the two objects passed using a case insensitive comparison.
			/// </summary>
			/// <param name="x">First object to be compared</param>
			/// <param name="y">Second object to be compared</param>
			/// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
			public int Compare(object x, object y)
			{
				int compareResult;
				ListViewItem listviewX, listviewY;

				// Cast the objects to be compared to ListViewItem objects
				listviewX = (ListViewItem)x;
				listviewY = (ListViewItem)y;

				// Compare the two items
				if (AllNumeric(listviewX.SubItems[ColumnToSort].Text) && AllNumeric(listviewY.SubItems[ColumnToSort].Text))
				{
					compareResult = ObjectCompare.Compare(Convert.ToInt32(listviewX.SubItems[ColumnToSort].Text),Convert.ToInt32(listviewY.SubItems[ColumnToSort].Text));
				}
				else
				{
					compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text);
				}

				// Calculate correct return value based on object comparison
				if (OrderOfSort == SortOrder.Ascending)
				{
					// Ascending sort is selected, return normal result of compare operation
					return compareResult;
				}
				else if (OrderOfSort == SortOrder.Descending)
				{
					// Descending sort is selected, return negative result of compare operation
					return (-compareResult);
				}
				else
				{
					// Return '0' to indicate they are equal
					return 0;
				}
			}

			/// <summary>
			/// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0').
			/// </summary>
			public int SortColumn
			{
				set
				{
					ColumnToSort = value;
				}
				get
				{
					return ColumnToSort;
				}
			}

			/// <summary>
			/// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending').
			/// </summary>
			public SortOrder Order
			{
				set
				{
					OrderOfSort = value;
				}
				get
				{
					return OrderOfSort;
				}
			}

		}
		private void SmartListView_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
		{
			// Determine if clicked column is already the column that is being sorted.
			if (e.Column == lvwColumnSorter.SortColumn)
			{
				// Reverse the current sort direction for this column.
				if (lvwColumnSorter.Order == SortOrder.Ascending)
				{
					lvwColumnSorter.Order = SortOrder.Descending;
				}
				else
				{
					lvwColumnSorter.Order = SortOrder.Ascending;
				}
			}
			else
			{
				// Set the column number that is to be sorted; default to ascending.
				lvwColumnSorter.SortColumn = e.Column;
				lvwColumnSorter.Order = SortOrder.Ascending;
			}

			// Perform the sort with these new sort options.
			this.Sort();

		}
		#endregion

	}
}

i couldnt attach to last post because of a javascript error.

this is a smart windows form to display lists. it uses the SmartListView that i created. By using this form, you can display any
list of objects and grab the selected ones from it.

SmartListForm.cs :

#region Name Spaces

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;

#endregion

namespace SmartControls
{
	public partial class SmartListForm : Form
	{
		#region Properties
		public IList DataSource
		{
			get
			{
				return smartListView1.DataSource;
			}
			set
			{
				if (value != null)
					smartListView1.DataSource = value;
				else
					throw new ApplicationException("DataSource can not be null");
			}
		}
		public string[] ColumnHeaders
		{
			set
			{
				smartListView1.ColumnHeaders = value;
			}
		}
		private IList selectedItems= null;
		public IList SelectedItems
		{
			get
			{
				return selectedItems;
			}
			set
			{
				selectedItems = value;
			}
		}
		#endregion

		#region Constructor
		public SmartListForm()
		{
			InitializeComponent();
		}
		public SmartListForm(IList _selectedItems)
		{
			SelectedItems = _selectedItems;
			InitializeComponent();
		}
		#endregion

		#region Event Handlers

		private void SmartListForm_Load(object sender, EventArgs e)
		{
			smartListView1.Items[0].Selected = true;
		}

		private void btnOK_Click(object sender, EventArgs e)
		{
			if (SelectedItems != null)
			{
				SelectedItems.Clear();
			   foreach (ListViewItem lvi in smartListView1.SelectedItems)
			   {
			      SelectedItems.Add(DataSource[Convert.ToInt32(lvi.Text)-1]);
			   }
			}
			DialogResult = DialogResult.OK;
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			DialogResult = DialogResult.Cancel;
		}
		private void smartListView1_DoubleClick(object sender, EventArgs e)
		{
			SelectedItems.Clear();
			SelectedItems.Add(DataSource[Convert.ToInt32(smartListView1.SelectedItems[0].Text)-1]);
			DialogResult = DialogResult.OK;
		}
		#endregion

	

	
	}
}

i attach the whole project to this post.

commented: I appreciate your work. Thanks for all of your hard work. +7
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.