Code:
using System.Collections;
using System.Runtime.InteropServices;
namespace System.Windows.Forms
{
public class exListView : ListView
{
private int _SortColumnIndex = -1;
public int SortColumnIndex
{
get
{
return _SortColumnIndex;
}
set
{
SetSortIcon(_SortColumnIndex, value);
_SortColumnIndex = value;
}
}
internal ColumnAttributes[] ColumnAttributes = new ColumnAttributes[100];
public exListView()
{
ListViewItemSorter = new exListViewItemSorter();
for (int i = 0; i < ColumnAttributes.Length; i++)
{
ColumnAttributes[i] = new ColumnAttributes(ColumnSortAlgorithm.String);
}
SendMessage(Handle, 0x127, 0x10001, 0);
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
SetWindowTheme(Handle, "Explorer", null);
SortColumnIndex = _SortColumnIndex;
}
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
SendMessage(Handle, 0x127, 0x10001, 0);
}
protected override void OnColumnClick(ColumnClickEventArgs e)
{
base.OnColumnClick(e);
Sorting = e.Column == _SortColumnIndex ? (Sorting == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending) : SortOrder.Ascending;
SortColumnIndex = e.Column;
Sort();
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
SendMessage(Handle, 0x127, 0x10001, 0);
}
private void SetSortIcon(int previous, int current)
{
IntPtr header = SendMessage(Handle, 0x101f, IntPtr.Zero, IntPtr.Zero);
HDITEM item;
if (previous != -1 && previous != current)
{
item = new HDITEM();
item.mask = 4;
SendMessage(header, 0x120b, (IntPtr)previous, ref item);
item.fmt &= ~0x0200 & ~0x0400;
SendMessage(header, 0x120c, (IntPtr)previous, ref item);
}
item = new HDITEM();
item.mask = 4;
SendMessage(header, 0x120b, (IntPtr)current, ref item);
if (Sorting == SortOrder.Ascending)
{
item.fmt &= ~0x0200;
item.fmt |= 0x0400;
}
else
{
item.fmt &= ~0x0400;
item.fmt |= 0x0200;
}
SendMessage(header, 0x120c, (IntPtr)current, ref item);
previous = current;
SetWindowTheme(Handle, "explorer", null);
}
public void SetColumnAttributes(int column, ColumnSortAlgorithm sortAlgorithm)
{
ColumnAttributes[column] = new ColumnAttributes(sortAlgorithm);
}
[StructLayout(LayoutKind.Sequential)]
private struct HDITEM
{
public int mask;
public int cxy;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszText;
public IntPtr hbm;
public int cchTextMax;
public int fmt;
public int lParam;
public int iImage;
public int iOrder;
}
[DllImport("user32.dll")]
static private extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
static private extern IntPtr SendMessage(IntPtr Handle, int msg, IntPtr wParam, ref HDITEM lParam);
[DllImport("user32.dll")]
public extern static int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
static private extern int SetWindowTheme(IntPtr hWnd, string textSubAppName, string textSubIdList);
}
public class ColumnAttributes
{
public ColumnSortAlgorithm SortAlgorithm { get; set; }
public ColumnAttributes(ColumnSortAlgorithm sortAlgorithm)
{
SortAlgorithm = sortAlgorithm;
}
}
public enum ColumnSortAlgorithm
{
String,
Number,
NumberOfSubItemTag,
IPAddress,
TextLength
}
public class exListViewItemSorter : IComparer
{
public int Compare(object x, object y)
{
try
{
ListViewItem lx = (ListViewItem)x, ly = (ListViewItem)y;
exListView view = (exListView)lx.ListView;
if (view.Sorting == SortOrder.None) return 0;
int col = view.SortColumnIndex;
string tx = lx.SubItems[col].Text, ty = ly.SubItems[col].Text;
int compare = 0;
switch (view.ColumnAttributes[col].SortAlgorithm)
{
case ColumnSortAlgorithm.String:
compare = tx.CompareTo(ty);
break;
case ColumnSortAlgorithm.Number:
compare = Convert.ToInt32(tx).CompareTo(Convert.ToInt32(ty));
break;
case ColumnSortAlgorithm.NumberOfSubItemTag:
string tax = "", tay = "";
if (col == 0)
{
tax = Convert.ToString(lx.Tag);
tay = Convert.ToString(ly.Tag);
}
else
{
tax = Convert.ToString(lx.SubItems[col].Tag);
tay = Convert.ToString(ly.SubItems[col].Tag);
}
compare = Convert.ToInt32(tax).CompareTo(Convert.ToInt32(tay));
break;
case ColumnSortAlgorithm.IPAddress:
string[] ip1 = tx.Split('.');
string[] ip2 = ty.Split('.');
for (int i = 0; i < 4; i++)
{
if (ip1[i] != ip2[i])
{
compare = Convert.ToInt32(ip1[i]).CompareTo(Convert.ToInt32(ip2[i]));
break;
}
}
break;
case ColumnSortAlgorithm.TextLength:
compare = tx.Length.CompareTo(ty.Length);
break;
}
return view.Sorting == SortOrder.Ascending ? compare : -compare;
}
catch
{
return 0;
}
}
}
}